<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet href="/firehose/news?altTemplate=FirehoseXslt" type="text/xsl" media="screen" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:umb="http://www.umbraco.com" umb:media-type="news">
    <channel>
        <atom:link href="https://umb.fyi/firehose/news" rel="self" type="application/rss+xml" />
        <title>UMB.FYI Firehose - News</title>
        <link>https://umb.fyi/firehose/news</link>
        <description>Aggregated news from the Umbraco community</description>
        <pubDate>Tue, 24 Oct 2023 14:27:33 Z</pubDate>
        <lastBuildDate>Sun, 06 Sep 2026 00:58:57 Z</lastBuildDate>
        <language>en</language>
        <generator>Umbraco</generator>
                <item>
                    <guid>https://marketplace.umbraco.com/package/utpro.feature.geolocation</guid>
                    <title>uTPro.Feature.GeoLocation</title>
                    <link>https://marketplace.umbraco.com/package/utpro.feature.geolocation</link>
                    <description><![CDATA[IP-based geolocation for Umbraco sites. Detects visitor country via CDN headers (Cloudflare CF-IPCountry, AWS CloudFront-Viewer-Country, Azure Front Door X-Azure-ClientIP) with an offline MMDB fallback (iplocate.io). Resolves country codes to .NET CultureInfo for seamless multi-language switching. Pluggable provider chain, Umbraco middleware integration, and configurable culture mapping.]]></description>
                    <pubDate>Sat, 05 Sep 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.automate.salesforce</guid>
                    <title>Umbraco.Community.Automate.Salesforce</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.automate.salesforce</link>
                    <description><![CDATA[Salesforce connection and actions for Umbraco Automate]]></description>
                    <pubDate>Fri, 04 Sep 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://www.thehumantech.agency/learn/writing-my-first-umbraco-extension-from-an-ai-button-to-generating-entire-pages/</guid>
                    <title>Writing My First Umbraco Extension: Building ThtaAI</title>
                    <link>https://www.thehumantech.agency/learn/writing-my-first-umbraco-extension-from-an-ai-button-to-generating-entire-pages/</link>
                    <description><![CDATA[Building my first Umbraco extension: lessons learned creating ThtaAI, from AI-powered property editors to full page generation and publishing.]]></description>
                    <pubDate>Thu, 03 Sep 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://skttl.dev/blog/the-ultimate-umbraco-site-structure-revisited/</guid>
                    <title>The ultimate Umbraco site structure, revisited</title>
                    <link>https://skttl.dev/blog/the-ultimate-umbraco-site-structure-revisited/</link>
                    <description><![CDATA[How I use the Ultimate Site Structure, with a custom URL provider and content finder that keep the frontpage separate from the site root.]]></description>
                    <pubDate>Thu, 03 Sep 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://owain.codes/blog/2026/september/initialsautolink/</guid>
                    <title>Initials.Autolink</title>
                    <link>https://owain.codes/blog/2026/september/initialsautolink/</link>
                    <description><![CDATA[Add a keyword, and every old article that mentions it links itself. Initials.AutoLink for Umbraco 17&#x2B;, and the first open source package from Initials Labs.]]></description>
                    <pubDate>Thu, 03 Sep 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.umbradesktop</guid>
                    <title>Umbraco.Community.UmbraDesktop</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.umbradesktop</link>
                    <description><![CDATA[An OS-style windowed desktop for the Umbraco backoffice. Open content, media, settings and other sections as real draggable, resizable windows and work in several of them side by side. Includes a grouped app launcher with pinnable apps, a taskbar, and per-app window chrome, all styled to match the backoffice.]]></description>
                    <pubDate>Thu, 03 Sep 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/initials.autolink</guid>
                    <title>Initials.AutoLink</title>
                    <link>https://marketplace.umbraco.com/package/initials.autolink</link>
                    <description><![CDATA[Turns keyword mentions in Umbraco rich text and markdown into links to the corresponding page or external link, at render time, with no editor action required. Stored markup is never modified, so an article picks up a link the day somebody adds the keyword. Keywords live in a backoffice section of their own rather than on your document types, and point at a page or an external URL through Umbraco&#x27;s Multi URL Picker. Shows which pages carry links and lets individual ones be switched off. Multilingual.]]></description>
                    <pubDate>Thu, 03 Sep 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://medium.com/@anujt2596/resetting-an-umbraco-backoffice-password-at-the-database-level-9a6cb9c2ed0a?source=rss-ef07e047ada5------2</guid>
                    <title>Resetting an Umbraco Backoffice Password at the Database Level</title>
                    <link>https://medium.com/@anujt2596/resetting-an-umbraco-backoffice-password-at-the-database-level-9a6cb9c2ed0a?source=rss-ef07e047ada5------2</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Wed, 02 Sep 2026 06:44:23 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://medium.com/@anujt2596/resetting-an-umbraco-backoffice-password-at-the-database-level-9a6cb9c2ed0a?source=rss------umbraco-5</guid>
                    <title>Resetting an Umbraco Backoffice Password at the Database Level</title>
                    <link>https://medium.com/@anujt2596/resetting-an-umbraco-backoffice-password-at-the-database-level-9a6cb9c2ed0a?source=rss------umbraco-5</link>
                    <description><![CDATA[&lt;div class=&quot;medium-feed-item&quot;&gt;&lt;p class=&quot;medium-feed-image&quot;&gt;&lt;a href=&quot;https://medium.com/@anujt2596/resetting-an-umbraco-backoffice-password-at-the-database-level-9a6cb9c2ed0a?source=rss------umbraco-5&quot;&gt;&lt;img src=&quot;https://cdn-images-1.medium.com/max/1917/1*jfiEI1FWPvdGHoAVJ57MQA.png&quot; width=&quot;1917&quot;&gt;&lt;/a&gt;&lt;/p&gt;&lt;p class=&quot;medium-feed-snippet&quot;&gt;Are you locked out of your Umbraco account?&lt;/p&gt;&lt;p class=&quot;medium-feed-link&quot;&gt;&lt;a href=&quot;https://medium.com/@anujt2596/resetting-an-umbraco-backoffice-password-at-the-database-level-9a6cb9c2ed0a?source=rss------umbraco-5&quot;&gt;Continue reading on Medium &#xBB;&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;]]></description>
                    <pubDate>Wed, 02 Sep 2026 06:44:23 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://cornehoskam.com/posts/meet-engageai-an-ai-copilot-built-for-marketers/</guid>
                    <title>Meet Engage.AI: an AI copilot built for marketers</title>
                    <link>https://cornehoskam.com/posts/meet-engageai-an-ai-copilot-built-for-marketers/</link>
                    <description><![CDATA[Umbraco Engage.AI is in public beta: an AI copilot answering marketer questions about campaigns, segments and A/B tests, straight from your Engage data.]]></description>
                    <pubDate>Wed, 02 Sep 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://github.com/abjerner/Limbo.Umbraco.BlockList/releases/tag/v17.0.0-alpha001</guid>
                    <title>Limbo.Umbraco.BlockList 17.0.0-alpha001</title>
                    <link>https://github.com/abjerner/Limbo.Umbraco.BlockList/releases/tag/v17.0.0-alpha001</link>
                    <description><![CDATA[Umbraco package that extends the functionality of Umbraco&#x27;s build-in block list.]]></description>
                    <pubDate>Tue, 01 Sep 2026 15:13:44 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                </item>
                <item>
                    <guid>https://www.nevitech.co.uk/blog/rebuilding-our-umbraco-website/</guid>
                    <title>Rebuilding our Umbraco Website</title>
                    <link>https://www.nevitech.co.uk/blog/rebuilding-our-umbraco-website/</link>
                    <description><![CDATA[Our own website spent years at the bottom of the list. Last year we rebuilt it on Umbraco 13, moved it to 17, rewrote every page and did the SEO work properly. Here is what we did and what we would do differently.]]></description>
                    <pubDate>Tue, 01 Sep 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://www.nevitech.co.uk/blog/umbraco-17-output-caching-part-2/</guid>
                    <title>Umbraco 17 Output Caching - Part 2</title>
                    <link>https://www.nevitech.co.uk/blog/umbraco-17-output-caching-part-2/</link>
                    <description><![CDATA[Umbraco 17 on .NET 10 is quick, so we did not need page caching at all. We built it anyway to see what was possible before trying it on a client site. The implementation, the rules for when not to cache, and what it cost.]]></description>
                    <pubDate>Tue, 01 Sep 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://www.nevitech.co.uk/blog/umbraco-csp-nonces-with-output-caching-part-3/</guid>
                    <title>Umbraco CSP Nonces with Output Caching - Part 3</title>
                    <link>https://www.nevitech.co.uk/blog/umbraco-csp-nonces-with-output-caching-part-3/</link>
                    <description><![CDATA[Cache a page containing a CSP nonce and every later visitor gets a stale nonce that no longer matches their header, so the browser blocks the lot. Most advice says pick one. Here is how to have both.]]></description>
                    <pubDate>Tue, 01 Sep 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/megaform.umbraco</guid>
                    <title>MegaForm.Umbraco</title>
                    <link>https://marketplace.umbraco.com/package/megaform.umbraco</link>
                    <description><![CDATA[MegaForm module for Umbraco CMS &#x2014; form builder, multi-view, submissions, and workflow extensibility.]]></description>
                    <pubDate>Tue, 01 Sep 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://skrift.io/issues/#131</guid>
                    <title>Skrift Issue #131</title>
                    <link>https://skrift.io/issues/#131</link>
                    <description><![CDATA[Featuring guest post by Paul Seal on &quot;I thought bots were attacking my site (it was me)&quot;]]></description>
                    <pubDate>Tue, 01 Sep 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                        <category>skrift</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/esatto.umbraco.backoffice.cookiescan</guid>
                    <title>Esatto.Umbraco.Backoffice.CookieScan</title>
                    <link>https://marketplace.umbraco.com/package/esatto.umbraco.backoffice.cookiescan</link>
                    <description><![CDATA[The site-side half of the Esatto cookie scanner. Adds one management-API endpoint that appends a scan&#x27;s findings to the cookie policy page as a draft - append-only, never publishing, never rewriting an editor&#x27;s legal wording - plus the API user and client credentials that authenticate the post. Companion to Esatto.Umbraco.Backoffice.CookieBanner, whose cookieDefinition element type and cookiePolicy page it writes into. Run the scan itself with the Esatto.CookieScan.Cli tool. Wiring is one AddCookieScan() call and one SeedCookieScanApiUserAsync() on start.]]></description>
                    <pubDate>Tue, 01 Sep 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://www.nevitech.co.uk/blog/rebuilding-our-umbraco-website-part-1/</guid>
                    <title>Rebuilding our Umbraco Website - Part 1</title>
                    <link>https://www.nevitech.co.uk/blog/rebuilding-our-umbraco-website-part-1/</link>
                    <description><![CDATA[Our own website spent years at the bottom of the list. Last year we rebuilt it on Umbraco 13, moved it to 17, rewrote every page and did the SEO work properly. Here is what we did and what we would do differently.]]></description>
                    <pubDate>Tue, 01 Sep 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://www.nevitech.co.uk/blog/umbraco-csp-nonces-with-output-caching/</guid>
                    <title>Umbraco CSP Nonces with Output Caching</title>
                    <link>https://www.nevitech.co.uk/blog/umbraco-csp-nonces-with-output-caching/</link>
                    <description><![CDATA[Cache a page containing a CSP nonce and every later visitor gets a stale nonce that no longer matches their header, so the browser blocks the lot. Most advice says pick one. Here is how to have both.]]></description>
                    <pubDate>Tue, 01 Sep 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://www.nevitech.co.uk/blog/umbraco-17-output-caching/</guid>
                    <title>Umbraco 17 Output Caching</title>
                    <link>https://www.nevitech.co.uk/blog/umbraco-17-output-caching/</link>
                    <description><![CDATA[Umbraco 17 on .NET 10 is quick, so we did not need page caching at all. We built it anyway to see what was possible before trying it on a client site. The implementation, the rules for when not to cache, and what it cost.]]></description>
                    <pubDate>Tue, 01 Sep 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://medium.com/@contacts_81271/umbraco-sicherheit-praxisleitfaden-zum-schutz-ihres-cms-29e1c26b0414?source=rss------umbraco-5</guid>
                    <title>Umbraco-Sicherheit: Praxisleitfaden zum Schutz Ihres CMS</title>
                    <link>https://medium.com/@contacts_81271/umbraco-sicherheit-praxisleitfaden-zum-schutz-ihres-cms-29e1c26b0414?source=rss------umbraco-5</link>
                    <description><![CDATA[&lt;div class=&quot;medium-feed-item&quot;&gt;&lt;p class=&quot;medium-feed-image&quot;&gt;&lt;a href=&quot;https://medium.com/@contacts_81271/umbraco-sicherheit-praxisleitfaden-zum-schutz-ihres-cms-29e1c26b0414?source=rss------umbraco-5&quot;&gt;&lt;img src=&quot;https://cdn-images-1.medium.com/max/1672/1*iCiI64uT0Ux6cHb9-fxglw.png&quot; width=&quot;1672&quot;&gt;&lt;/a&gt;&lt;/p&gt;&lt;p class=&quot;medium-feed-snippet&quot;&gt;Umbraco geh&amp;#xF6;rt zu den weltweit f&amp;#xFC;hrenden Open-Source-Enterprise-CMS auf .NET-Basis und bietet standardm&amp;#xE4;&amp;#xDF;ig eine extrem stabile&amp;#x2026;&lt;/p&gt;&lt;p class=&quot;medium-feed-link&quot;&gt;&lt;a href=&quot;https://medium.com/@contacts_81271/umbraco-sicherheit-praxisleitfaden-zum-schutz-ihres-cms-29e1c26b0414?source=rss------umbraco-5&quot;&gt;Continue reading on Medium &#xBB;&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;]]></description>
                    <pubDate>Mon, 31 Aug 2026 16:05:57 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://github.com/limbo-works/Limbo.Umbraco.BorgerDk/releases/tag/v17.0.0-alpha001</guid>
                    <title>Limbo.Umbraco.BorgerDk 17.0.0-alpha001</title>
                    <link>https://github.com/limbo-works/Limbo.Umbraco.BorgerDk/releases/tag/v17.0.0-alpha001</link>
                    <description><![CDATA[Umbraco package for integrating with the Borger.dk web service.]]></description>
                    <pubDate>Mon, 31 Aug 2026 13:42:48 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                </item>
                <item>
                    <guid>https://dev.to/bernadet/umbraco-2-way-relations-umbraco-features-you-didnt-know-you-needed-3a2d</guid>
                    <title>Umbraco 2-way relations - Umbraco Features You Didn&#x27;t Know You Needed</title>
                    <link>https://dev.to/bernadet/umbraco-2-way-relations-umbraco-features-you-didnt-know-you-needed-3a2d</link>
                    <description><![CDATA[&lt;h2&gt;&#xA;  &#xA;  &#xA;  Relations in Umbraco: asking the question your picker can&#x27;t answer&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;You&#x27;ve probably used a Content Picker (or a Multinode Treepicker) to wire content together. A page picks a banner, a landing page picks a set of related articles, a policy picks the older policy it replaces. That gives you one direction for free: open the page, and you can see exactly what it points at.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;But pickers only answer one question. &lt;strong&gt;&quot;What does this page use?&quot;&lt;/strong&gt; is easy. &lt;strong&gt;&quot;What uses this?&quot;&lt;/strong&gt; is not. The picker property lives on the node that did the picking, not on the node that got picked. If you want to go the other way, your only option is make the pages hierarchical or to loop over every piece of content in the tree and check whether its picker field happens to mention the node you care about.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;That&#x27;s exactly the gap Umbraco&#x27;s &lt;a href=&quot;https://docs.umbraco.com/umbraco-cms/model-your-content/content-types-and-structure/relations&quot; rel=&quot;noopener noreferrer&quot;&gt;Relations&lt;/a&gt; are for. A Relation is a first-class, queryable link between two entities that you can walk in either direction via &lt;a href=&quot;https://docs.umbraco.com/umbraco-cms/extend-your-project/server-side-extensions/management/using-services/relationservice&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;code&gt;IRelationService&lt;/code&gt;&lt;/a&gt;:  &lt;code&gt;GetByParentId&lt;/code&gt; for &quot;what does this point at&quot;, &lt;code&gt;GetByChildId&lt;/code&gt; for &quot;what points at this&quot;. This post walks through a small example project that uses a Relation to answer a question a picker alone can&#x27;t.&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  The scenario: policies that supersede each other&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Imagine a &quot;Policy Page&quot; doctype. Editors write a new policy, and pick (via a normal Multinode Treepicker) which older policy or policies it supersedes. That&#x27;s a completely standard one-way relationship: new policy &#x2192; picks &#x2192; old policy.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The picker answers &quot;which policies does this one supersede&quot; perfectly well. What it can&#x27;t answer is the question an editor actually asks when they land on an old policy page: &lt;strong&gt;&quot;Has this been superseded, and by what?&quot;&lt;/strong&gt; Nothing on that old policy&#x27;s own data points back to the newer one &#x2014; the pick lives entirely on the other node. Short of scanning every Policy Page in the site for one whose &lt;code&gt;supersedes&lt;/code&gt; field happens to mention this node&#x27;s ID, there&#x27;s no way to answer it.&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  Why not just use Umbraco&#x27;s built-in &quot;Related Document&quot; relation?&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Umbraco ships a built-in relation type for exactly this kind of document-to-document link, aliased &lt;code&gt;umbDocument&lt;/code&gt;. It would technically work &#x2014; except it&#x27;s a single shared, undifferentiated bucket. Anything in Umbraco (media picker usages, link pickers, whatever else) can write a generic document-to-document reference into it, so a reverse lookup on &lt;code&gt;umbDocument&lt;/code&gt; can&#x27;t reliably tell you &quot;which policy superseded this one&quot; versus any other unrelated reference someone else recorded into the same bucket.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The fix is a &lt;strong&gt;relation type of your own&lt;/strong&gt; &lt;code&gt;policySupersedes&lt;/code&gt; so a reverse lookup on that alias only ever returns the thing you actually care about.&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  The implementation&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;The example lives in four files.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;1. The doctype and the picker.&lt;/strong&gt; Add a &quot;Policy Page&quot; content type with a &lt;code&gt;bodyText&lt;/code&gt; richtext property and a &lt;code&gt;supersedes&lt;/code&gt; Multinode Treepicker, filtered so it can only pick other Policy Pages.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;This is the plain, one-way picker. Nothing special yet.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;2. Syncing the picker into a Relation.&lt;/strong&gt; &lt;code&gt;PolicySupersedesRelationSyncHandler&lt;/code&gt; listens for &lt;code&gt;ContentSavedNotification&lt;/code&gt;. Every time a Policy Page is saved, it wipes out whatever relations already exist for that node under the &lt;code&gt;policySupersedes&lt;/code&gt; alias and rebuilds them from whatever&#x27;s currently picked:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight csharp&quot;&gt;&lt;code&gt;    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Handle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ContentSavedNotification&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;notification&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;        &lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IContent&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;content&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;notification&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SavedEntities&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&#xA;        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ContentType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Alias&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PolicyPageContentTypeAlias&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&#xA;            &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;                &lt;span class=&quot;nf&quot;&gt;SyncSupersedesRelations&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&#xA;            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&#xA;    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;SyncSupersedesRelations&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IContent&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;newPolicy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;        &lt;span class=&quot;n&quot;&gt;IRelationType&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;relationType&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_relationService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetRelationTypeByAlias&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ExampleConstants&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RelationTypeAlias&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&#xA;            &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;CreateRelationType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;&#xA;&#xA;        &lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IRelation&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;existingRelation&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_relationService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetByParentId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;newPolicy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ExampleConstants&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RelationTypeAlias&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&#xA;        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;            &lt;span class=&quot;n&quot;&gt;_relationService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Delete&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;existingRelation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&#xA;        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&#xA;        &lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;supersededPolicyId&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetPickedContentIds&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;newPolicy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&#xA;        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;            &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;relation&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Relation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;newPolicy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;supersededPolicyId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;relationType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&#xA;            &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;                &lt;span class=&quot;n&quot;&gt;Comment&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;$&quot;Marked as superseded on &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DateTime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UtcNow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&#xA;            &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;&#xA;            &lt;span class=&quot;n&quot;&gt;_relationService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Save&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;relation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&#xA;        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;As shown above, you can also add a comment to a relation, which we use to store additional information on when the policy was superseded in our example, which can then be shown again on the Policy page. &lt;/p&gt;&#xA;&#xA;&lt;p&gt;The relation type itself is created on demand as non-bidirectional, &lt;code&gt;Document-to-Document&lt;/code&gt;, and importantly &lt;code&gt;isDependency: true&lt;/code&gt;:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight csharp&quot;&gt;&lt;code&gt;    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IRelationType&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;CreateRelationType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;        &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;relationType&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;RelationType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&#xA;            &lt;span class=&quot;s&quot;&gt;&quot;Policy Supersedes&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&#xA;            &lt;span class=&quot;n&quot;&gt;ExampleConstants&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RelationTypeAlias&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&#xA;            &lt;span class=&quot;n&quot;&gt;isBidrectional&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&#xA;            &lt;span class=&quot;n&quot;&gt;parentObjectType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Constants&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ObjectTypes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&#xA;            &lt;span class=&quot;n&quot;&gt;childObjectType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Constants&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ObjectTypes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&#xA;            &lt;span class=&quot;n&quot;&gt;isDependency&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&#xA;            &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&#xA;        &lt;span class=&quot;n&quot;&gt;_relationService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Save&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;relationType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&#xA;        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;relationType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;3. Wiring it up.&lt;/strong&gt; Add the notification handler with the standard &lt;code&gt;IComposer&lt;/code&gt; boilerplate, nothing Relations-specific.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;4. Reading both directions in the view.&lt;/strong&gt; This is where the payoff shows up. &lt;code&gt;policyPage.cshtml&lt;/code&gt; reads the picker property directly for the forward direction, and calls &lt;code&gt;RelationService.GetByChildId&lt;/code&gt; for the reverse direction, the direction the picker alone could never give you:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight csharp&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;supersededByRelations&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RelationService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetByChildId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ExampleConstants&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RelationTypeAlias&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight csharp&quot;&gt;&lt;code&gt;&lt;span class=&quot;nf&quot;&gt;@if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;supersededByRelations&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Any&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;border: 2px solid red; padding: 1em; margin-bottom: 1em;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;&#xA;        &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strong&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;This&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;policy&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;has&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;been&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;superseded&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&amp;lt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strong&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;&#xA;        &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ul&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;&#xA;            &lt;span class=&quot;nf&quot;&gt;@foreach&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;relation&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;supersededByRelations&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&#xA;            &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;                &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;newerPolicy&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ContentQuery&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;relation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ParentId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&#xA;                &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;newerPolicy&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&#xA;                    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;                        &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;li&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;&#xA;                            &lt;span class=&quot;n&quot;&gt;Replaced&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;by&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;@newerPolicy.Url()&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;@newerPolicy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;&#xA;                            &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;br&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;/&amp;gt;&lt;/span&gt;&#xA;                            &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;small&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;@relation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Comment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;small&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;&#xA;                        &lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;li&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;&#xA;                    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;        &lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ul&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;div&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;Open an old policy that&#x27;s been superseded, and the page now knows it  without ever scanning the rest of the tree.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&quot;https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fck836v1ca0lzekvqhwbg.png&quot; class=&quot;article-body-image-wrapper&quot;&gt;&lt;img src=&quot;https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fck836v1ca0lzekvqhwbg.png&quot; alt=&quot;Old policy page superseded&quot; width=&quot;587&quot; height=&quot;316&quot;&gt;&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  The other payoff: you can&#x27;t delete a still-referenced policy without a warning&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Setting &lt;code&gt;IsDependency = true&lt;/code&gt; on the relation type isn&#x27;t just documentation, it plugs straight into Umbraco&#x27;s own dependency checks. Try to delete or unpublish a policy that&#x27;s still marked as superseded by another one, and the backoffice will warn you it&#x27;s in use, the same way it would for a media item still referenced by a Content Picker elsewhere.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;This is the practical version of &quot;what if you need to delete a shared component, but three pages still reference it&quot;: with a plain picker, deleting the referenced item is silent and the reference just breaks. With a proper Relation, Umbraco already knows something depends on it and stops you.&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  When to reach for this&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;strong&gt;A picker is enough&lt;/strong&gt; when you only ever need to ask &quot;what does this content point at&quot;, the normal, forward direction.&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;strong&gt;The built-in &quot;Related Document&quot; relation&lt;/strong&gt; is fine for generic, low-stakes cross-references where you don&#x27;t care about precision on the reverse lookup.&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;strong&gt;A custom relation type&lt;/strong&gt; is worth the extra notification-handler code when you need a reverse lookup you can trust &quot;what points at me&quot; and/or you want deletion/unpublish safety for content that&#x27;s still depended on.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;Pickers tell you what a page uses. Relations are what let you ask the question in the other direction.&lt;/p&gt;]]></description>
                    <pubDate>Mon, 31 Aug 2026 09:47:52 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbfy.umbraco.collaboration</guid>
                    <title>UMBFY.Umbraco.Collaboration</title>
                    <link>https://marketplace.umbraco.com/package/umbfy.umbraco.collaboration</link>
                    <description><![CDATA[UMBFY Collaboration adds real-time presence, editing awareness, change notifications, and conflict prevention to the Umbraco backoffice for Umbraco CMS 17.x and 18.x. Redis is optional for multi-node hosts.]]></description>
                    <pubDate>Mon, 31 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://umbraco.com/blog/building-software-with-a-clean-conscience-why-umbraco-is-now-a-certified-b-corporation/</guid>
                    <title>Building Software with a Clean Conscience</title>
                    <link>https://umbraco.com/blog/building-software-with-a-clean-conscience-why-umbraco-is-now-a-certified-b-corporation/</link>
                    <description><![CDATA[Umbraco earns B Corp Certification, validating 20 years of ESG performance, 53% female hire diversity, ISO 27001 security, and sustainable tech growth.]]></description>
                    <pubDate>Mon, 31 Aug 2026 00:00:00 Z</pubDate>
                        <category>hq</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://github.com/limbo-works/Limbo.Umbraco.Innomate/releases/tag/v17.0.0-alpha001</guid>
                    <title>Limbo.Umbraco.Innomate 17.0.0-alpha001</title>
                    <link>https://github.com/limbo-works/Limbo.Umbraco.Innomate/releases/tag/v17.0.0-alpha001</link>
                    <description><![CDATA[Umbraco integration for the Innomate API.]]></description>
                    <pubDate>Sun, 30 Aug 2026 11:28:05 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                </item>
                <item>
                    <guid>https://www.proworks.com/blog/archive/announcing-the-new-proworks-umbraco-media-audit-package/</guid>
                    <title>Announcing the new ProWorks Umbraco Media Audit package!</title>
                    <link>https://www.proworks.com/blog/archive/announcing-the-new-proworks-umbraco-media-audit-package/</link>
                    <description><![CDATA[One of the things I&#x27;ve been asked for by clients more often than I&#x27;d expect in the last few months is to help them audit all their media so that they can clean out everything they&#x27;re not using.&#xA;The good news is that with access to a database and Claude, writing a little reusable python script the scrape everything was exceptionally easy. But by the third request I&#x27;d decided maybe that rather than doing this for my clients I could give them the autonomy and flexibility to do this by themselves on demand. After all, it&#x27;s a waste of their time and budget to need a developer to audit their media whenever they&#x27;re wanting to clean it up. The benefit of this package is it gives your content editors the autonomy to audit and clean up their own media on their own schedule whenever they want!&#xA;So with this, I present to you the new ProWorks Umbraco Media Audit package that I&#x27;ve released for Umbraco 17! This tidy little package adds a dashboard into your media section where you can run an audit on all of your media, discover what&#x27;s in use and what isn&#x27;t all in one location without having to click through item after item.&#xA;&#xA;There&#x27;s some caveats of course - the audit script is only searching for anything that&#x27;s directly referenced with a picker. If a client pasted a URL manually anywhere or is linking to an item in an e-mail marketing campaign, there&#x27;s currently no way for the Media Audit to tell. So it&#x27;s important that human eyes look at these items when determining if they&#x27;re still relevant, and getting detail on an item by item basis is very easy to do.&#xA;&#xA;And once an admin-only user has determined none of the media is in use, they can mark them all for deletion and move them into the recycle bin. If they&#x27;re really content all is well then there&#x27;s even a purge button to clear the recycle bin and remove the items from disk!&#xA;&#xA;We have a few features that we want to add in the future:&#xA;&#xA;Field auditing - do you have your alt text or captions filled out? We&#x27;d like to make this &quot;plug and play&quot; so you can add any fields that you want and the tool will check if they&#x27;re empty.&#xA;Integrating the above with Umbraco AI - if a field is empty, fill it in with Umbraco AI&#x27;s integrations to read media files and write alt text.&#xA;Display a thumbnail of the item in the dashboard (if it&#x27;s an image) to help with visual recognition&#xA;Check if images don&#x27;t have crops selected or set&#xA;&#xA;Are there any features that you&#x27;d love to see? Let us know!]]></description>
                    <pubDate>Fri, 28 Aug 2026 21:00:20 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://www.johanreitsma.com/blogs/quick-tip-extending-the-delivery-apis-content-response/</guid>
                    <title>Quick Tip: Extending the Delivery API&#x27;s Content Response</title>
                    <link>https://www.johanreitsma.com/blogs/quick-tip-extending-the-delivery-apis-content-response/</link>
                    <description><![CDATA[A quick look at how to extend Umbraco 17&#x2019;s Delivery API response with content from elsewhere in the content tree, without building a custom endpoint....]]></description>
                    <pubDate>Fri, 28 Aug 2026 20:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://www.youtube.com/watch?v=Mp-5Uy7pZ9E</guid>
                    <title>umbraCoffee - Back To School</title>
                    <link>https://www.youtube.com/watch?v=Mp-5Uy7pZ9E</link>
                    <description><![CDATA[Welcome to your monthly dose of #umbraCoffee&#x200B;&#x200B;&#x200B;&#x200B;&#x200B;&#x200B;&#x200B;&#x200B;&#x200B;&#x200B;&#x200B;&#x200B;! Your hosts - Marcin and Callum - together with their guest(s) will drive through all of the community news and happenings in the Umbraco world. So... grab a cuppa, join us LIVE and enjoy!&#xA;&#xA;See ya?!&#xA;&#xA;---&#xA;&#x2615; Wanna buy us a coffee/pizza/donuts?&#xA;https://www.buymeacoffee.com/umbracoffee&#xA;---&#xA;&#xA;Notes:&#xA;&#xA;// TODO]]></description>
                    <pubDate>Fri, 28 Aug 2026 10:02:44 Z</pubDate>
                        <category>community</category>
                        <category>youtube</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.adpreview</guid>
                    <title>SplatDev.Umbraco.Plugins.AdPreview</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.adpreview</link>
                    <description><![CDATA[Image ad preview property editor for Umbraco 13 and 17.]]></description>
                    <pubDate>Fri, 28 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://umbracofreelancer.net/blog/umbraco-ai-ships-with-nothing-in-it-and-that-is-the-whole-job/</guid>
                    <title>Umbraco AI ships with nothing in it</title>
                    <link>https://umbracofreelancer.net/blog/umbraco-ai-ships-with-nothing-in-it-and-that-is-the-whole-job/</link>
                    <description><![CDATA[Umbraco AI ships with nothing in it]]></description>
                    <pubDate>Thu, 27 Aug 2026 21:18:00 Z</pubDate>
                        <category>blog</category>
                        <category>community</category>
                </item>
                <item>
                    <guid>https://umbracocommunity.social/@owaincodes/117167568702510172</guid>
                    <title>OC.UFMFallbacks has been updated</title>
                    <link>https://umbracocommunity.social/@owaincodes/117167568702510172</link>
                    <description><![CDATA[OC.UFMFallbacks has been updated]]></description>
                    <pubDate>Thu, 27 Aug 2026 15:53:00 Z</pubDate>
                        <category>community</category>
                        <category>social</category>
                        <category>mastodon</category>
                </item>
                <item>
                    <guid>https://www.arroact.com/blogs/umbraco-18-elements-a-new-way-to-manage-reusable-content/</guid>
                    <title>Umbraco 18 Elements: A New Way to Manage Reusable Content</title>
                    <link>https://www.arroact.com/blogs/umbraco-18-elements-a-new-way-to-manage-reusable-content/</link>
                    <description><![CDATA[Umbraco 18 Elements: A New Way to Manage Reusable Content]]></description>
                    <pubDate>Thu, 27 Aug 2026 13:56:00 Z</pubDate>
                        <category>blog</category>
                        <category>community</category>
                </item>
                <item>
                    <guid>https://www.nathanielnunes.com/blog/umbraco-automate-teams-notification</guid>
                    <title>Notify a Teams channel when you publish content, using Umbraco Automate</title>
                    <link>https://www.nathanielnunes.com/blog/umbraco-automate-teams-notification</link>
                    <description><![CDATA[Use Umbraco Automate to post a notification to a Microsoft Teams channel whenever content is published, with no custom C#. A step by step walkthrough on Umbraco 17.]]></description>
                    <pubDate>Thu, 27 Aug 2026 11:30:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/usync.automate.actions</guid>
                    <title>uSync.Automate.Actions</title>
                    <link>https://marketplace.umbraco.com/package/usync.automate.actions</link>
                    <description><![CDATA[Run uSync imports, exports and reports from Umbraco Automate workflows, and trigger workflows from uSync events.]]></description>
                    <pubDate>Thu, 27 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/jumoo.translationmanager.automate</guid>
                    <title>Jumoo.TranslationManager.Automate</title>
                    <link>https://marketplace.umbraco.com/package/jumoo.translationmanager.automate</link>
                    <description><![CDATA[Create, submit and approve Translation Manager jobs from Umbraco Automate workflows, and start workflows from translation events.]]></description>
                    <pubDate>Thu, 27 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/usync.automate</guid>
                    <title>uSync.Automate</title>
                    <link>https://marketplace.umbraco.com/package/usync.automate</link>
                    <description><![CDATA[uSync for Umbraco Automate settings]]></description>
                    <pubDate>Thu, 27 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/usync.automate.actions.complete</guid>
                    <title>uSync.Automate.Actions.Complete</title>
                    <link>https://marketplace.umbraco.com/package/usync.automate.actions.complete</link>
                    <description><![CDATA[Push or pull content/media and settings items, and create restore points, via uSync.Complete&#x27;s publisher from Umbraco Automate workflows, and trigger workflows when a publish is received.]]></description>
                    <pubDate>Thu, 27 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/dotsee.responsiveimages</guid>
                    <title>DotSee.ResponsiveImages</title>
                    <link>https://marketplace.umbraco.com/package/dotsee.responsiveimages</link>
                    <description><![CDATA[Responsive image markup for Umbraco, driven entirely by configuration. Define breakpoint rule sets once in appsettings.json, then render them anywhere with a tag helper or from Razor: picture elements with per-breakpoint art direction, img tags with srcset and sizes, and responsive CSS background images with focal-point-aware background-position.&#xA;&#xA;Every crop is anchored on the focal point the editor set in the back office. That is the part a CDN cannot do for you: an edge resizer has to guess where the subject of an image is, while Umbraco already knows, because someone chose it. Faces stay in frame at every breakpoint.&#xA;&#xA;Lazy loading is native browser lazy loading plus inline LQIP (Low-Quality Image Placeholder) blur-ups generated at render time, so there is no runtime JavaScript dependency at all: no lazysizes, no bundler, nothing extra to ship. Above-the-fold images can instead be marked to load eagerly at high fetch priority, and they register preload hints that a single tag helper emits in your layout head, which is what actually moves your Largest Contentful Paint.&#xA;&#xA;A strict Content Security Policy is supported first class: pass a nonce and the placeholder styles and scripts are emitted as nonce-tagged blocks instead of inline attributes. Rendered markup and resolved rule sets are cached, and the cache is invalidated automatically when content or media changes, including through the cache refreshers that reach every node in a load-balanced setup.&#xA;&#xA;Optionally, hand the resizing off to the edge: point a rule set at Cloudflare Image Transformations and the package composes Cloudflare image URLs, focal point and all, instead of asking your origin to crop. Optional CDN cache purging drops replaced images from the edge when an editor saves new media. Both are off by default.&#xA;&#xA;The package ships a JSON schema for full appsettings IntelliSense and auto-registers through an Umbraco composer, so installing it and adding one addTagHelper line is the whole setup.]]></description>
                    <pubDate>Thu, 27 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://world.hey.com/boriseetgerink/automated-umbraco-log- monitoring-and-bug-fixing-on-a-claude-code-routine-fec9eb6a</guid>
                    <title>Automated Umbraco log monitoring and bug fixing on a Claude Code Routine</title>
                    <link>https://world.hey.com/boriseetgerink/automated-umbraco-log- monitoring-and-bug-fixing-on-a-claude-code-routine-fec9eb6a</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Wed, 26 Aug 2026 11:12:00 Z</pubDate>
                        <category>blog</category>
                        <category>community</category>
                </item>
                <item>
                    <guid>https://github.com/limbo-works/Limbo.Umbraco.Emply/releases/tag/v13.0.0</guid>
                    <title>Limbo.Umbraco.Emply 13.0.0</title>
                    <link>https://github.com/limbo-works/Limbo.Umbraco.Emply/releases/tag/v13.0.0</link>
                    <description><![CDATA[Umbraco integration for the Emply API.]]></description>
                    <pubDate>Wed, 26 Aug 2026 09:03:43 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                </item>
                <item>
                    <guid>https://shazwazza.com/post/examine-v4-is-out/</guid>
                    <title>Examine v4 is out </title>
                    <link>https://shazwazza.com/post/examine-v4-is-out/</link>
                    <description><![CDATA[Examine v4 is out - Shazwazza]]></description>
                    <pubDate>Wed, 26 Aug 2026 00:30:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.powertoys</guid>
                    <title>Umbraco.Community.PowerToys</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.powertoys</link>
                    <description><![CDATA[A dashboard in the Umbraco Settings section that collects small backoffice admin tools (&quot;power toys&quot;) in one place, each with its own on/off switch. Ships with tools including a Navbar Clock, Login Customizer, Logo Changer, Help Menu Editor, Environment Indicator, Theme Maker, and Dashboard Manager, and other packages can register their own power toys onto the same dashboard without touching this package&#x27;s code.]]></description>
                    <pubDate>Wed, 26 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbrascript</guid>
                    <title>UmbraScript</title>
                    <link>https://marketplace.umbraco.com/package/umbrascript</link>
                    <description><![CDATA[UmbraScript is an xTalk-style scripting language for inspecting and automating content and media in Umbraco CMS. UmbraScript is a interpreted and dynamic language that should feel natural to developers and content editors alike.]]></description>
                    <pubDate>Wed, 26 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/our.umbraco.screensaver</guid>
                    <title>Our.Umbraco.Screensaver</title>
                    <link>https://marketplace.umbraco.com/package/our.umbraco.screensaver</link>
                    <description><![CDATA[After a few minutes without activity the backoffice logo takes over the screen and bounces around it like the old DVD logo, counting perfect corner hits. Any keystroke or mouse movement dismisses it. Because the overlay is opaque it doubles as a privacy screen when you walk away from your desk.]]></description>
                    <pubDate>Wed, 26 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://www.nevitech.co.uk/blog/why-i-choose-umbraco-over-wordpress/</guid>
                    <title>Why I choose Umbraco over WordPress</title>
                    <link>https://www.nevitech.co.uk/blog/why-i-choose-umbraco-over-wordpress/</link>
                    <description><![CDATA[Umbraco and WordPress solve different problems, and after years of building on both I know which one I want to still be maintaining in five years.]]></description>
                    <pubDate>Wed, 26 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://github.com/skybrud/Skybrud.Umbraco.Redirects/releases/tag/v17.1.0-beta001</guid>
                    <title>Skybrud.Umbraco.Redirects 17.1.0-beta001</title>
                    <link>https://github.com/skybrud/Skybrud.Umbraco.Redirects/releases/tag/v17.1.0-beta001</link>
                    <description><![CDATA[Award winning redirects manager for Umbraco.]]></description>
                    <pubDate>Tue, 25 Aug 2026 20:14:01 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                </item>
                <item>
                    <guid>https://github.com/abjerner/Limbo.Umbraco.Iddqd/releases/tag/v17.0.0-alpha004</guid>
                    <title>Limbo.Umbraco.Iddqd 17.0.0-alpha004</title>
                    <link>https://github.com/abjerner/Limbo.Umbraco.Iddqd/releases/tag/v17.0.0-alpha004</link>
                    <description><![CDATA[Limbo.Umbraco.Iddqd package with various developer oriented improvements for the Umbraco backoffice.]]></description>
                    <pubDate>Tue, 25 Aug 2026 14:24:02 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                </item>
                <item>
                    <guid>https://github.com/abjerner/Limbo.Umbraco.Iddqd/releases/tag/v17.0.0-alpha003</guid>
                    <title>Limbo.Umbraco.Iddqd 17.0.0-alpha003</title>
                    <link>https://github.com/abjerner/Limbo.Umbraco.Iddqd/releases/tag/v17.0.0-alpha003</link>
                    <description><![CDATA[Limbo.Umbraco.Iddqd package with various developer oriented improvements for the Umbraco backoffice.]]></description>
                    <pubDate>Tue, 25 Aug 2026 10:49:53 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                </item>
                <item>
                    <guid>https://www.thehumantech.agency/learn/upgrading-umbraco-13-to-17-what-we-learned/</guid>
                    <title>Upgrading Umbraco 13 to 17: What We Learned</title>
                    <link>https://www.thehumantech.agency/learn/upgrading-umbraco-13-to-17-what-we-learned/</link>
                    <description><![CDATA[What we learned upgrading a large production website from Umbraco 13 to 17, covering migrations, APIs, AngularJS, property editors, Forms, content and deployment.]]></description>
                    <pubDate>Tue, 25 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.themes.portfolio</guid>
                    <title>SplatDev.Umbraco.Themes.Portfolio</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.themes.portfolio</link>
                    <description><![CDATA[Portfolio theme for Umbraco - project grid, project detail, filtering, lightbox, about]]></description>
                    <pubDate>Tue, 25 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.socialmedia.channels.propertyeditor</guid>
                    <title>SplatDev.Umbraco.Plugins.SocialMedia.Channels.PropertyEditor</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.socialmedia.channels.propertyeditor</link>
                    <description><![CDATA[Social Media Channels property editor for Umbraco 17.]]></description>
                    <pubDate>Tue, 25 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.themes.forum</guid>
                    <title>SplatDev.Umbraco.Themes.Forum</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.themes.forum</link>
                    <description><![CDATA[Forum/community theme for Umbraco - thread list, post view, user profiles, categories]]></description>
                    <pubDate>Tue, 25 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://ddev.com/blog/umbraco-on-ddev/</guid>
                    <title>Umbraco on DDEV: .NET, SQL Server, and the generic project type</title>
                    <link>https://ddev.com/blog/umbraco-on-ddev/</link>
                    <description><![CDATA[An experiment in running Umbraco CMS and .NET 10 under DDEV, using the generic project type, a custom web image, and Azure SQL Edge.]]></description>
                    <pubDate>Tue, 25 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbfy.umbraco.mediaorder</guid>
                    <title>UMBFY.Umbraco.MediaOrder</title>
                    <link>https://marketplace.umbraco.com/package/umbfy.umbraco.mediaorder</link>
                    <description><![CDATA[Adds newest-first ordering and Name, Upload Date, and File Size sorting to the Umbraco Media Library.]]></description>
                    <pubDate>Tue, 25 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/esatto.umbraco.backoffice.cookiebanner</guid>
                    <title>Esatto.Umbraco.Backoffice.CookieBanner</title>
                    <link>https://marketplace.umbraco.com/package/esatto.umbraco.backoffice.cookiebanner</link>
                    <description><![CDATA[Turnkey GDPR/ePrivacy cookie consent for Umbraco 17 &amp; 18. A blocking consent dialog, per-category gating of scripts and embeds through the &lt;consent-script&gt; and &lt;consent-embed&gt; tag helpers, Google Consent Mode v2 signalling, an editor-managed cookie registry (cookieDefinition element type plus a cookieRegistry block list) and a rendered cookie policy page. Wiring is two lines of Razor and one app.UseCookieConsent() call.]]></description>
                    <pubDate>Mon, 24 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://dev.to/erikjanwestendorp/building-a-cloudflare-integration-for-umbraco-automate-3f8m</guid>
                    <title>Building a Cloudflare Integration for Umbraco Automate</title>
                    <link>https://dev.to/erikjanwestendorp/building-a-cloudflare-integration-for-umbraco-automate-3f8m</link>
                    <description><![CDATA[&lt;p&gt;When I first started experimenting with Umbraco Automate, I wanted to find a real-world use case instead of creating an integration just for the sake of trying the API. It didn&#x27;t take long to find one. On several Umbraco projects, we use Cloudflare in front of the website. When content changes, there are situations where we want to invalidate the cached version of the affected page.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Traditionally, I would solve this in code:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight plaintext&quot;&gt;&lt;code&gt;Content published&#xA;      &#x2193;&#xA;Notification handler&#xA;      &#x2193;&#xA;Determine published URLs&#xA;      &#x2193;&#xA;Call Cloudflare API&#xA;      &#x2193;&#xA;Purge cache&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;That works. But after looking at Automate, I started wondering:&lt;/p&gt;&#xA;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;What if the application doesn&#x27;t need to know anything about Cloudflare at all?&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&#xA;&lt;p&gt;Instead, publishing content could simply trigger an automation, with small reusable actions taking care of the individual steps.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;That idea eventually resulted in three NuGet packages:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;code&gt;Umbraco.Community.Automate&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;Umbraco.Community.Automate.Extensions&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;Umbraco.Community.Automate.Cloudflare&lt;/code&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;All currently available as version &lt;code&gt;17.0.0&lt;/code&gt; for Umbraco 17.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;This post describes how I got there, some of the problems I encountered, and what I learned about extending Umbraco Automate along the way.&lt;/p&gt;&#xA;&#xA;&#xA;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  Starting with the obvious solution&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;My first idea was simple. Umbraco Automate already provides a &lt;strong&gt;Content Published&lt;/strong&gt; trigger, so I wanted to create a Cloudflare action that could take the published page and purge it from Cloudflare.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Something like:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight plaintext&quot;&gt;&lt;code&gt;Content Published&#xA;      &#x2193;&#xA;Purge Cloudflare&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;The Cloudflare API itself makes this fairly straightforward.To purge specific URLs you can send a request to:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight plaintext&quot;&gt;&lt;code&gt;POST /client/v4/zones/{zoneId}/purge_cache&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;with:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight json&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;files&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;    &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;https://www.example.com/some-page/&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;So initially I thought the Cloudflare action could simply accept the URL of the published page.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The Content Published trigger doesn&#x27;t provide a URL.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;It exposes information such as:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight plaintext&quot;&gt;&lt;code&gt;contentKey&#xA;contentName&#xA;contentTypeKey&#xA;contentTypeAlias&#xA;cultures&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;And actually, that makes sense. A URL isn&#x27;t necessarily a property of the publish event.&lt;/p&gt;&#xA;&#xA;&#xA;&#xA;&#xA;&lt;h1&gt;&#xA;  &#xA;  &#xA;  A content item doesn&#x27;t necessarily have one URL&#xA;&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;This became the first interesting part of the implementation.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Consider a multilingual Umbraco website:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight plaintext&quot;&gt;&lt;code&gt;https://www.example.com/&#xA;https://www.example.com/en/&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;Now add multiple hostnames, which is perfectly valid in an Umbraco installation:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight plaintext&quot;&gt;&lt;code&gt;https://www.example-a.com/&#xA;https://www.example-a.com/en/&#xA;&#xA;https://www.example-b.com/&#xA;https://www.example-b.com/en/&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;For a single content item, asking:&lt;/p&gt;&#xA;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;What is the URL?&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&#xA;&lt;p&gt;is therefore not always the right question.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The better question is:&lt;/p&gt;&#xA;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;What are the published URLs for this content item and culture?&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&#xA;&lt;p&gt;That distinction ended up having quite a large influence on the package design.&lt;/p&gt;&#xA;&#xA;&#xA;&#xA;&#xA;&lt;h1&gt;&#xA;  &#xA;  &#xA;  Separating Umbraco from Cloudflare&#xA;&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;My first instinct was to put the URL resolution inside the Cloudflare action.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The action could receive:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight plaintext&quot;&gt;&lt;code&gt;Content Key&#xA;Culture&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;and internally:&lt;/p&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Resolve the Umbraco content.&lt;/li&gt;&#xA;&lt;li&gt;Determine its URLs.&lt;/li&gt;&#xA;&lt;li&gt;Call Cloudflare.&lt;/li&gt;&#xA;&lt;li&gt;Purge those URLs.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;p&gt;But that didn&#x27;t feel right.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Resolving published URLs has nothing to do with Cloudflare.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The same functionality could be useful when:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;notifying an external API;&lt;/li&gt;&#xA;&lt;li&gt;updating a search index;&lt;/li&gt;&#xA;&lt;li&gt;sending a webhook;&lt;/li&gt;&#xA;&lt;li&gt;invalidating another CDN;&lt;/li&gt;&#xA;&lt;li&gt;generating a sitemap;&lt;/li&gt;&#xA;&lt;li&gt;or building another Automate workflow.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;So instead I created a generic action:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight plaintext&quot;&gt;&lt;code&gt;Get Published Content URLs&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;and moved it into a separate package:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight plaintext&quot;&gt;&lt;code&gt;Umbraco.Community.Automate.Extensions&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;Cloudflare became its own integration:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight plaintext&quot;&gt;&lt;code&gt;Umbraco.Community.Automate.Cloudflare&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;This allows Automate to do what it is good at: composing small pieces of functionality.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The workflow becomes:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight plaintext&quot;&gt;&lt;code&gt;Content Published&#xA;      &#x2193;&#xA;For Each Culture&#xA;      &#x2193;&#xA;Get Published Content URLs&#xA;      &#x2193;&#xA;Purge Cloudflare URLs&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;That separation is probably the design decision I&#x27;m happiest with.&lt;/p&gt;&#xA;&#xA;&#xA;&#xA;&#xA;&lt;h1&gt;&#xA;  &#xA;  &#xA;  Building Get Published Content URLs&#xA;&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;The generic action receives a content key and culture.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Its settings are roughly:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight csharp&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;sealed&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;GetPublishedContentUrlsSettings&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Guid&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ContentKey&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&#xA;    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Culture&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Empty&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;The output deliberately contains an array:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight csharp&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;sealed&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;GetPublishedContentUrlsOutput&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Guid&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ContentKey&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&#xA;    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Culture&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Empty&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&#xA;&#xA;    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Urls&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[];&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;Notice that it&#x27;s &lt;code&gt;Urls&lt;/code&gt;, not &lt;code&gt;Url&lt;/code&gt;.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;This is important for installations where a culture is available through multiple domains.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Conceptually the action does:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight plaintext&quot;&gt;&lt;code&gt;Content Key &#x2B; Culture&#xA;          &#x2193;&#xA; Umbraco published content&#xA;          &#x2193;&#xA; Primary &#x2B; alternative URLs&#xA;          &#x2193;&#xA;       string[]&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;That output can then be consumed by any other Automate action.&lt;/p&gt;&#xA;&#xA;&#xA;&#xA;&#xA;&lt;h1&gt;&#xA;  &#xA;  &#xA;  Lesson learned: be careful with service lifetimes&#xA;&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;While building the action I ran into another useful lesson.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;My first implementation injected &lt;code&gt;IPublishedContentQuery&lt;/code&gt; directly into the action.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;That resulted in:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight plaintext&quot;&gt;&lt;code&gt;Cannot consume scoped service&#xA;&#x27;Umbraco.Cms.Core.IPublishedContentQuery&#x27;&#xA;from singleton&#xA;&#x27;GetPublishedContentUrlsAction&#x27;.&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;Automate actions are registered as singletons, while several Umbraco services used for published content are scoped.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Injecting one directly into a singleton therefore isn&#x27;t safe.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Instead, the action needs to work with the appropriate Umbraco context/service scope when resolving published content.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;It&#x27;s an easy mistake to make when building your first Automate extension because the action itself looks very similar to a normal service.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The important takeaway:&lt;/p&gt;&#xA;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;Always consider the lifetime of the services you inject into an Automate action.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&#xA;&#xA;&#xA;&#xA;&lt;h1&gt;&#xA;  &#xA;  &#xA;  Cultures introduced another interesting problem&#xA;&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;The Content Published trigger exposes &lt;code&gt;cultures&lt;/code&gt;.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Not &lt;code&gt;culture&lt;/code&gt;.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;That means a single publish operation can involve multiple cultures.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The obvious workflow is therefore:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight plaintext&quot;&gt;&lt;code&gt;Content Published&#xA;      &#x2193;&#xA;For Each&#xA;      &#x2193;&#xA;Get Published Content URLs&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;The collection for the loop is:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight plaintext&quot;&gt;&lt;code&gt;${ trigger.cultures }&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;And inside the loop the current culture is:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight plaintext&quot;&gt;&lt;code&gt;${ loop.item }&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;Initially I accidentally passed:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight plaintext&quot;&gt;&lt;code&gt;${ trigger.cultures }&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;directly into the action&#x27;s &lt;code&gt;Culture&lt;/code&gt; field.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;That resulted in something like:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight plaintext&quot;&gt;&lt;code&gt;[&quot;es&quot;]&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;being passed as the culture instead of:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight plaintext&quot;&gt;&lt;code&gt;es&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;and consequently:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight plaintext&quot;&gt;&lt;code&gt;Content &#x27;&amp;lt;guid&amp;gt;&#x27; is not published for culture &#x27;[&quot;es&quot;]&#x27;.&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;The correct pattern is:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight plaintext&quot;&gt;&lt;code&gt;For Each:&#xA;${ trigger.cultures }&#xA;&#xA;Get Published Content URLs:&#xA;&#xA;Content Key:&#xA;${ trigger.contentKey }&#xA;&#xA;Culture:&#xA;${ loop.item }&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;A small mistake, but a good example of why understanding the difference between a collection binding and the current loop item matters.&lt;/p&gt;&#xA;&#xA;&#xA;&#xA;&#xA;&lt;h1&gt;&#xA;  &#xA;  &#xA;  Then I wanted to purge multiple URLs at once&#xA;&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;Initially the Cloudflare package had:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight plaintext&quot;&gt;&lt;code&gt;Purge Cloudflare URL&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;with:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight csharp&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Url&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Empty&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;This worked perfectly when combined with another &lt;code&gt;For Each&lt;/code&gt;:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight plaintext&quot;&gt;&lt;code&gt;Get Published Content URLs&#xA;      &#x2193;&#xA;For Each URL&#xA;      &#x2193;&#xA;Purge Cloudflare URL&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;But Cloudflare already accepts multiple URLs in one request.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;So why make one HTTP request per URL?&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I changed the action to:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight plaintext&quot;&gt;&lt;code&gt;Purge Cloudflare URLs&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;and the Cloudflare client now accepts a collection:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight csharp&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;Task&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;PurgeUrlsAsync&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&#xA;    &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;apiToken&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&#xA;    &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;zoneId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&#xA;    &lt;span class=&quot;n&quot;&gt;IEnumerable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;urls&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&#xA;    &lt;span class=&quot;n&quot;&gt;CancellationToken&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cancellationToken&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;The resulting request can contain all URLs:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight json&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;files&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;    &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;https://www.example-a.com/en/&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;    &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;https://www.example-b.com/en/&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;This makes the workflow much nicer:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight plaintext&quot;&gt;&lt;code&gt;Get Published Content URLs&#xA;      &#x2193;&#xA;Purge Cloudflare URLs&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;At least, that was the idea.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;And then I learned something interesting about Automate bindings.&lt;/p&gt;&#xA;&#xA;&#xA;&#xA;&#xA;&lt;h1&gt;&#xA;  &#xA;  &#xA;  Binding an array isn&#x27;t the same as binding a string&#xA;&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;My first settings model looked perfectly reasonable:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight csharp&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;sealed&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;PurgeUrlsSettings&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Urls&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[];&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;The previous action already returned:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight csharp&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Urls&lt;/span&gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;so I expected this binding to work:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight plaintext&quot;&gt;&lt;code&gt;${ previous.urls }&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;Instead Automate failed before the action was even executed:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight plaintext&quot;&gt;&lt;code&gt;Failed to resolve model &#x27;community.cloudflare.purgeUrls&#x27;&#xA;to type PurgeUrlsSettings.&#xA;&#xA;The JSON value could not be converted to System.String[].&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;That was confusing at first because the source value really was a &lt;code&gt;string[]&lt;/code&gt;.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The important detail is how action settings are stored.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The binding itself is initially represented as:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight json&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;urls&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;${ previous.urls }&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;That&#x27;s a string expression.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;If the property is already declared as &lt;code&gt;string[]&lt;/code&gt;, JSON deserialization needs to happen before that expression can resolve to its collection value.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;So:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight plaintext&quot;&gt;&lt;code&gt;&quot;${ previous.urls }&quot;&#xA;        &#x2193;&#xA;Deserialize as string[]&#xA;        &#x2193;&#xA;&#x1F4A5;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&lt;h1&gt;&#xA;  &#xA;  &#xA;  Looking at For Each provided the answer&#xA;&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;The interesting thing was that this already worked:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight plaintext&quot;&gt;&lt;code&gt;Get Published Content URLs&#xA;      &#x2193;&#xA;For Each&#xA;&#xA;Collection:&#xA;${ previous.urls }&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;So Automate clearly &lt;em&gt;could&lt;/em&gt; consume my array.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;That led me into the Automate source code.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The built-in &lt;code&gt;For Each&lt;/code&gt; doesn&#x27;t define its collection setting as an array.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Instead, conceptually it does this:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight csharp&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Collection&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Empty&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;The setting contains the &lt;strong&gt;binding expression&lt;/strong&gt;, not the resolved collection.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The expression is evaluated later at runtime.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;That same approach works nicely for the Cloudflare action.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The setting can remain:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight csharp&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;sealed&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;PurgeUrlsSettings&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Urls&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Empty&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;and the configured value remains:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight plaintext&quot;&gt;&lt;code&gt;${ previous.urls }&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;At runtime, Automate&#x27;s &lt;code&gt;BindingEvaluator&lt;/code&gt; can evaluate the raw expression:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight csharp&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_bindingEvaluator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;EvaluateRaw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&#xA;    &lt;span class=&quot;n&quot;&gt;settings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Urls&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&#xA;    &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BindingData&lt;/span&gt;&#xA;        &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Dictionary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&amp;gt;());&lt;/span&gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;The action can then turn that resolved value into the collection it needs.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;This was probably the most interesting technical lesson from building the package.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Sometimes the type of a &lt;strong&gt;configuration property&lt;/strong&gt; shouldn&#x27;t represent the type of the eventual runtime value.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;In this case:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight plaintext&quot;&gt;&lt;code&gt;Setting&#xA;string expression&#xA;      &#x2193;&#xA;BindingEvaluator&#xA;      &#x2193;&#xA;runtime collection&#xA;      &#x2193;&#xA;Cloudflare API&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;is a better model.&lt;/p&gt;&#xA;&#xA;&#xA;&#xA;&#xA;&lt;h1&gt;&#xA;  &#xA;  &#xA;  Normalizing the URLs&#xA;&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;Before sending anything to Cloudflare, the action normalizes the collection:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight csharp&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;urls&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;urls&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Where&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;IsNullOrWhiteSpace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Select&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Trim&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Distinct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;StringComparer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;OrdinalIgnoreCase&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToArray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;Then it verifies that something remains:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight csharp&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;urls&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Length&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ActionResult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Failed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&#xA;        &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ArgumentException&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&#xA;            &lt;span class=&quot;s&quot;&gt;&quot;At least one URL is required.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;and validates the URLs:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight csharp&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;invalidUrl&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Find&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&#xA;    &lt;span class=&quot;n&quot;&gt;urls&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&#xA;    &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Uri&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;TryCreate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&#xA;        &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&#xA;        &lt;span class=&quot;n&quot;&gt;UriKind&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Absolute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&#xA;        &lt;span class=&quot;k&quot;&gt;out&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;&#xA;&#xA;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;invalidUrl&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ActionResult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Failed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&#xA;        &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ArgumentException&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&#xA;            &lt;span class=&quot;s&quot;&gt;$&quot;&#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;invalidUrl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&#x27; is not a valid absolute URL.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;Only after that does the action call Cloudflare.&lt;/p&gt;&#xA;&#xA;&#xA;&#xA;&#xA;&lt;h1&gt;&#xA;  &#xA;  &#xA;  Creating a reusable Cloudflare connection&#xA;&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;I didn&#x27;t want API tokens and zone IDs to be configured on every action.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Automate has a connection concept for exactly this purpose, so the Cloudflare package provides its own connection type.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The connection contains information such as:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight plaintext&quot;&gt;&lt;code&gt;Account ID&#xA;Zone ID&#xA;API Token&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;The API token can also be validated against Cloudflare.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Cloudflare provides an endpoint for checking whether a token is valid and active, which makes the connection test much more useful than simply checking whether a value was entered.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;A successful response looks roughly like:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight json&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;result&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;status&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;active&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;success&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;This gives users feedback while configuring the connection instead of waiting for their first automation run to fail.&lt;/p&gt;&#xA;&#xA;&#xA;&#xA;&#xA;&lt;h1&gt;&#xA;  &#xA;  &#xA;  Keep API tokens scoped&#xA;&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;For the Cloudflare API token, I recommend granting only the permissions required by the workflow.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;For cache purging, don&#x27;t use a token with unnecessary account-wide permissions.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The connection should know:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight plaintext&quot;&gt;&lt;code&gt;API Token&#xA;Zone ID&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;and the action should only perform the operation it was designed for.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;It&#x27;s a small detail, but integrations like these make security boundaries very visible.&lt;/p&gt;&#xA;&#xA;&#xA;&#xA;&#xA;&lt;h1&gt;&#xA;  &#xA;  &#xA;  The resulting packages&#xA;&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;The experiment eventually became three packages.&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  Umbraco.Community.Automate&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;The convenience package.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Installing it brings in the complete collection:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight shell&quot;&gt;&lt;code&gt;dotnet add package Umbraco.Community.Automate&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  Umbraco.Community.Automate.Extensions&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Generic Automate building blocks:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight shell&quot;&gt;&lt;code&gt;dotnet add package Umbraco.Community.Automate.Extensions&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;Currently including:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight plaintext&quot;&gt;&lt;code&gt;Get Published Content URLs&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  Umbraco.Community.Automate.Cloudflare&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;The Cloudflare integration:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight shell&quot;&gt;&lt;code&gt;dotnet add package Umbraco.Community.Automate.Cloudflare&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;Currently providing the Cloudflare connection and cache purge functionality.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The packages are versioned alongside their supported Umbraco major version, so the first stable release is:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight plaintext&quot;&gt;&lt;code&gt;17.0.0&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;for Umbraco 17.&lt;/p&gt;&#xA;&#xA;&#xA;&#xA;&#xA;&lt;h1&gt;&#xA;  &#xA;  &#xA;  Why I like this approach&#xA;&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;The part I like most isn&#x27;t actually the Cloudflare API integration.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Calling an HTTP API isn&#x27;t particularly complicated.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The interesting part is the separation of responsibilities.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Instead of writing:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight csharp&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ContentPublishedHandler&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;    &lt;span class=&quot;c1&quot;&gt;// Find content&lt;/span&gt;&#xA;    &lt;span class=&quot;c1&quot;&gt;// Determine cultures&lt;/span&gt;&#xA;    &lt;span class=&quot;c1&quot;&gt;// Determine domains&lt;/span&gt;&#xA;    &lt;span class=&quot;c1&quot;&gt;// Resolve URLs&lt;/span&gt;&#xA;    &lt;span class=&quot;c1&quot;&gt;// Read Cloudflare configuration&lt;/span&gt;&#xA;    &lt;span class=&quot;c1&quot;&gt;// Call Cloudflare&lt;/span&gt;&#xA;    &lt;span class=&quot;c1&quot;&gt;// Handle failures&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;we can create reusable building blocks:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight plaintext&quot;&gt;&lt;code&gt;Content Published&#xA;      &#x2193;&#xA;For Each Culture&#xA;      &#x2193;&#xA;Get Published Content URLs&#xA;      &#x2193;&#xA;Purge Cloudflare URLs&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;And tomorrow somebody could build:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight plaintext&quot;&gt;&lt;code&gt;Content Published&#xA;      &#x2193;&#xA;Get Published Content URLs&#xA;      &#x2193;&#xA;Notify external service&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;or:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight plaintext&quot;&gt;&lt;code&gt;Content Published&#xA;      &#x2193;&#xA;Get Published Content URLs&#xA;      &#x2193;&#xA;Update search index&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;without changing &lt;code&gt;Get Published Content URLs&lt;/code&gt;.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;That&#x27;s where I think Automate becomes really interesting.&lt;/p&gt;&#xA;&#xA;&#xA;&#xA;&#xA;&lt;h1&gt;&#xA;  &#xA;  &#xA;  What I learned&#xA;&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;A few things stood out while building these packages.&lt;/p&gt;&#xA;&#xA;&lt;h3&gt;&#xA;  &#xA;  &#xA;  Actions should do one thing&#xA;&lt;/h3&gt;&#xA;&#xA;&lt;p&gt;&lt;code&gt;Get Published Content URLs&lt;/code&gt; shouldn&#x27;t know Cloudflare exists.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;And &lt;code&gt;Purge Cloudflare URLs&lt;/code&gt; shouldn&#x27;t need to know anything about Umbraco content.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The workflow connects them.&lt;/p&gt;&#xA;&#xA;&lt;h3&gt;&#xA;  &#xA;  &#xA;  Model collections explicitly&#xA;&lt;/h3&gt;&#xA;&#xA;&lt;p&gt;A published content item can have multiple cultures, and one culture can have multiple URLs.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Designing around collections from the start avoids assumptions that only work for simple websites.&lt;/p&gt;&#xA;&#xA;&lt;h3&gt;&#xA;  &#xA;  &#xA;  Bindings are runtime values&#xA;&lt;/h3&gt;&#xA;&#xA;&lt;p&gt;A binding expression such as:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight plaintext&quot;&gt;&lt;code&gt;${ previous.urls }&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;is stored as a string but may resolve to something completely different at runtime.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Looking at how Automate&#x27;s own &lt;code&gt;For Each&lt;/code&gt; implementation handles this was extremely useful.&lt;/p&gt;&#xA;&#xA;&lt;h3&gt;&#xA;  &#xA;  &#xA;  Watch your DI lifetimes&#xA;&lt;/h3&gt;&#xA;&#xA;&lt;p&gt;Automate actions and Umbraco scoped services don&#x27;t necessarily share the same lifetime.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Be careful when injecting services such as published-content APIs directly into actions.&lt;/p&gt;&#xA;&#xA;&lt;h3&gt;&#xA;  &#xA;  &#xA;  Composition beats coupling&#xA;&lt;/h3&gt;&#xA;&#xA;&lt;p&gt;The Cloudflare use case resulted in a generic action that turned out to be useful completely independently of Cloudflare.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;That&#x27;s a good sign that the responsibility belongs in its own extension.&lt;/p&gt;&#xA;&#xA;&#xA;&#xA;&#xA;&lt;h1&gt;&#xA;  &#xA;  &#xA;  What&#x27;s next?&#xA;&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;There are plenty of directions this could go.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Cloudflare supports more than purging individual URLs, so possible future actions include:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight plaintext&quot;&gt;&lt;code&gt;Purge by cache tag&#xA;Purge by prefix&#xA;Purge by hostname&#xA;Purge everything&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;But I don&#x27;t want one giant &quot;Cloudflare action&quot; with every possible option.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I&#x27;d rather keep each operation explicit and let Automate compose them.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The generic Extensions package also opens the door to other reusable Umbraco actions that aren&#x27;t tied to a specific integration.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;And that&#x27;s probably what I find most interesting about Automate: once you start thinking in small triggers, actions and outputs, you quickly start seeing automation opportunities everywhere.&lt;/p&gt;&#xA;&#xA;&#xA;&#xA;&#xA;&lt;h1&gt;&#xA;  &#xA;  &#xA;  Try it&#xA;&lt;/h1&gt;&#xA;&#xA;&lt;p&gt;The packages are available on NuGet:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight plaintext&quot;&gt;&lt;code&gt;Umbraco.Community.Automate&#xA;Umbraco.Community.Automate.Extensions&#xA;Umbraco.Community.Automate.Cloudflare&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;Source code, examples and issues are available on GitHub:&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&quot;https://github.com/erikjanwestendorp/Umbraco.Community.Automate&quot; rel=&quot;noopener noreferrer&quot;&gt;https://github.com/erikjanwestendorp/Umbraco.Community.Automate&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The project is open source, so feedback, ideas, issues and pull requests are very welcome.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;If you&#x27;re experimenting with Umbraco Automate as well, I&#x27;d love to hear what kind of integrations or reusable actions you&#x27;re building.&lt;/p&gt;]]></description>
                    <pubDate>Sun, 23 Aug 2026 11:37:09 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://www.nevitech.co.uk/blog/building-my-own-umbraco-lamp/</guid>
                    <title>Building my own Umbraco Lamp</title>
                    <link>https://www.nevitech.co.uk/blog/building-my-own-umbraco-lamp/</link>
                    <description><![CDATA[I have wanted an UmbLamp ever since Matt Brailsford posted it back in November 2023, but I did not own a 3D printer. That finally changed this July, so I ordered the parts and built one. Here is what I used, what went wrong, and the one mistake worth avoiding before you start.]]></description>
                    <pubDate>Sun, 23 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umb.elementfinder</guid>
                    <title>Umb.ElementFinder</title>
                    <link>https://marketplace.umbraco.com/package/umb.elementfinder</link>
                    <description><![CDATA[Find and track where Umbraco Element Types are used across your content pages, with a clear dashboard view of their usage and references.]]></description>
                    <pubDate>Sun, 23 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/njobdesk.umbraco</guid>
                    <title>NJobDesk.Umbraco</title>
                    <link>https://marketplace.umbraco.com/package/njobdesk.umbraco</link>
                    <description><![CDATA[Umbraco backoffice integration for NJobDesk, the scheduler-agnostic jobs dashboard for .NET: a Settings-section dashboard guarded by backoffice authentication, wired to any NJobDesk scheduler provider (Umbraco recurring jobs, Quartz via uQuartz, Hangfire). Supports Umbraco 16 and 17.]]></description>
                    <pubDate>Sun, 23 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://github.com/limbo-works/Limbo.Umbraco.Skyfish/releases/tag/v17.0.0-alpha001</guid>
                    <title>Limbo.Umbraco.Skyfish 17.0.0-alpha001</title>
                    <link>https://github.com/limbo-works/Limbo.Umbraco.Skyfish/releases/tag/v17.0.0-alpha001</link>
                    <description><![CDATA[Video picker for inserting Skyfish videos in Umbraco.]]></description>
                    <pubDate>Fri, 21 Aug 2026 12:06:14 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                </item>
                <item>
                    <guid>https://github.com/abjerner/Limbo.Umbraco.Iddqd/releases/tag/v17.0.0-alpha002</guid>
                    <title>Limbo.Umbraco.Iddqd 17.0.0-alpha002</title>
                    <link>https://github.com/abjerner/Limbo.Umbraco.Iddqd/releases/tag/v17.0.0-alpha002</link>
                    <description><![CDATA[Limbo.Umbraco.Iddqd package with various developer oriented improvements for the Umbraco backoffice.]]></description>
                    <pubDate>Fri, 21 Aug 2026 08:39:56 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.advancedpermissions.ai</guid>
                    <title>Umbraco.Community.AdvancedPermissions.AI</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.advancedpermissions.ai</link>
                    <description><![CDATA[Optional AI companion for Advanced Permissions for Umbraco. It makes the Umbraco backoffice copilot permission-aware, so editors can ask in plain language who can do what, why an action is blocked, and what would fix it, plus audit a user group or a branch of the tree for risks and get the permission model itself explained. Every answer is computed by the package&#x27;s own permission-resolution engine, including the reasoning behind it, so the copilot stops guessing. Strictly read-only. Requires Umbraco AI with a configured copilot chat.]]></description>
                    <pubDate>Fri, 21 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.automate.extensions</guid>
                    <title>Umbraco.Community.Automate.Extensions</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.automate.extensions</link>
                    <description><![CDATA[Generic reusable actions and extensions for Umbraco Automate, including helpers for resolving published content URLs by culture and hostname.]]></description>
                    <pubDate>Fri, 21 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://kjac.dev/posts/from-examine-to-umbraco-search/</guid>
                    <title>From Examine to Umbraco Search</title>
                    <link>https://kjac.dev/posts/from-examine-to-umbraco-search/</link>
                    <description><![CDATA[Demonstrating an approach to migrate a site from Examine to Umbraco Search]]></description>
                    <pubDate>Fri, 21 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://medium.com/@teamAaitek/need-senior-cms-talent-fast-stop-waiting-months-for-recruitment-20ed26ef4f95?source=rss------umbraco-5</guid>
                    <title>Need Senior CMS Talent Fast? Stop Waiting Months for Recruitment.</title>
                    <link>https://medium.com/@teamAaitek/need-senior-cms-talent-fast-stop-waiting-months-for-recruitment-20ed26ef4f95?source=rss------umbraco-5</link>
                    <description><![CDATA[&lt;div class=&quot;medium-feed-item&quot;&gt;&lt;p class=&quot;medium-feed-image&quot;&gt;&lt;a href=&quot;https://medium.com/@teamAaitek/need-senior-cms-talent-fast-stop-waiting-months-for-recruitment-20ed26ef4f95?source=rss------umbraco-5&quot;&gt;&lt;img src=&quot;https://cdn-images-1.medium.com/max/1200/1*uld--j19fzIFjtUGzTLR2w.png&quot; width=&quot;1200&quot;&gt;&lt;/a&gt;&lt;/p&gt;&lt;p class=&quot;medium-feed-snippet&quot;&gt;Scaling an enterprise digital project often hits the same wall: finding vetted, certified senior developers who can hit the ground running&amp;#x2026;&lt;/p&gt;&lt;p class=&quot;medium-feed-link&quot;&gt;&lt;a href=&quot;https://medium.com/@teamAaitek/need-senior-cms-talent-fast-stop-waiting-months-for-recruitment-20ed26ef4f95?source=rss------umbraco-5&quot;&gt;Continue reading on Medium &#xBB;&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;]]></description>
                    <pubDate>Thu, 20 Aug 2026 23:33:53 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://mattbrailsford.dev/introducing-copilot-workspace</guid>
                    <title>Introducing Umbraco AI Copilot Workspace</title>
                    <link>https://mattbrailsford.dev/introducing-copilot-workspace</link>
                    <description><![CDATA[The RC for Umbraco AI Copilot Workspace just went out on our open release branches, so it&#x2019;s time to properly introduce it.&#xA;If you&#x2019;ve used Umbraco...]]></description>
                    <pubDate>Thu, 20 Aug 2026 09:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/chatixy.umbraco</guid>
                    <title>Chatixy.Umbraco</title>
                    <link>https://marketplace.umbraco.com/package/chatixy.umbraco</link>
                    <description><![CDATA[Adds the Chatixy AI support agent to every front-end page of an Umbraco site. Install the package, set your widget key in appsettings.json - no Program.cs or template changes.]]></description>
                    <pubDate>Thu, 20 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/phases.umbraco.stickynotes</guid>
                    <title>Phases.Umbraco.StickyNotes</title>
                    <link>https://marketplace.umbraco.com/package/phases.umbraco.stickynotes</link>
                    <description><![CDATA[Leave internal sticky notes in the backoffice. A floating button opens draggable, colour-coded notes with formatting, images, and a notes list. Notes stay in the editor&#x27;s browser and never appear on the public site.]]></description>
                    <pubDate>Thu, 20 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.automate</guid>
                    <title>Umbraco.Community.Automate</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.automate</link>
                    <description><![CDATA[A collection of community-built extensions and integrations for Umbraco Automate, providing reusable building blocks for creating powerful automation workflows.]]></description>
                    <pubDate>Thu, 20 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.automate.cloudflare</guid>
                    <title>Umbraco.Community.Automate.Cloudflare</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.automate.cloudflare</link>
                    <description><![CDATA[A Cloudflare integration for Umbraco Automate that adds a reusable connection and actions for purging cached URLs as part of configurable automation workflows.]]></description>
                    <pubDate>Thu, 20 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/automatic.umbraco.documentgenerator</guid>
                    <title>Automatic.Umbraco.DocumentGenerator</title>
                    <link>https://marketplace.umbraco.com/package/automatic.umbraco.documentgenerator</link>
                    <description><![CDATA[Turn design screenshots into a working Umbraco schema. Upload mockups and the package proposes Document Types, Element Types and properties, then seeds a matching content tree - into the Document Type folder you choose, under the Content node you choose, varying by culture where you need it. Every proposal is reviewable and editable before anything is written, so you keep control of the schema. Supports Google Gemini, OpenAI, Anthropic Claude and self-hosted Ollama. Umbraco 14 and above.]]></description>
                    <pubDate>Thu, 20 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/digitalwonderlab.alttextassistant</guid>
                    <title>DigitalWonderlab.AltTextAssistant</title>
                    <link>https://marketplace.umbraco.com/package/digitalwonderlab.alttextassistant</link>
                    <description><![CDATA[Find and fix images missing alt text in Umbraco. A Media section dashboard lists every image with no alt text and lets editors add it inline, with one-click AI suggestions (Anthropic Claude, OpenAI, or Google Gemini vision) and bulk-suggest across the page. Bring your own API key. Works on Umbraco Cloud and all hosting environments.]]></description>
                    <pubDate>Thu, 20 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://github.com/limbo-works/Limbo.Umbraco.DreamBroker/releases/tag/v17.0.0-alpha001</guid>
                    <title>Limbo.Umbraco.DreamBroker 17.0.0-alpha001</title>
                    <link>https://github.com/limbo-works/Limbo.Umbraco.DreamBroker/releases/tag/v17.0.0-alpha001</link>
                    <description><![CDATA[Video picker for inserting DreamBroker videos in Umbraco.]]></description>
                    <pubDate>Wed, 19 Aug 2026 13:06:14 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.lgpd</guid>
                    <title>SplatDev.Umbraco.Plugins.Lgpd</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.lgpd</link>
                    <description><![CDATA[LGPD (Lei 13.709/2018) compliance for Umbraco: append-only consent with the ten legal bases of art. 7, the nine data subject rights of art. 18 with the 15-day deadline of art. 19, the record of processing operations of art. 37, and the encarregado disclosure of art. 41. Front-end consent banner and backoffice dashboard. Supports Umbraco 13 (net8.0) and Umbraco 17 (net10.0).]]></description>
                    <pubDate>Wed, 19 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/techxot.umbraco.aireadiness</guid>
                    <title>Techxot.Umbraco.AiReadiness</title>
                    <link>https://marketplace.umbraco.com/package/techxot.umbraco.aireadiness</link>
                    <description><![CDATA[Scores how readable your pages are to AI answer engines, generates JSON-LD from a page&#x27;s own&#xA;      content, and tracks the score on every publish so a regression is visible. Requires an InMotion&#xA;      subscription for scoring.]]></description>
                    <pubDate>Wed, 19 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.googleanalytics</guid>
                    <title>SplatDev.Umbraco.Plugins.GoogleAnalytics</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.googleanalytics</link>
                    <description><![CDATA[Google Analytics GA4 integration for Umbraco &#x2014; store tracking/measurement ID in settings and inject the GA4 script. Supports Umbraco 13 and 17.]]></description>
                    <pubDate>Wed, 19 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/proworks.umbraco.mediaaudit</guid>
                    <title>ProWorks.Umbraco.MediaAudit</title>
                    <link>https://marketplace.umbraco.com/package/proworks.umbraco.mediaaudit</link>
                    <description><![CDATA[Audit your Umbraco CMS (v17&#x2B;) media library right from the backoffice: classify every item as Used or Unused, drill into exactly what references it, and safely delete or purge the rest with a full accountability log.]]></description>
                    <pubDate>Wed, 19 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.aivisibility.v13</guid>
                    <title>Umbraco.Community.AiVisibility.V13</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.aivisibility.v13</link>
                    <description><![CDATA[The Umbraco 13 / .NET 8 lite SKU: Markdown page rendering, llms.txt, and robots.txt audit for ChatGPT, Claude, Perplexity, Gemini, and Bing Copilot &#x2014; configured via appsettings.json (no Backoffice dashboards).]]></description>
                    <pubDate>Tue, 18 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://www.goldfinch.me/blog/umbraco-automate-developer-automation-or-marketing-automation</guid>
                    <title>Umbraco Automate: Developer Automation or Marketing Automation?</title>
                    <link>https://www.goldfinch.me/blog/umbraco-automate-developer-automation-or-marketing-automation</link>
                    <description><![CDATA[Umbraco Automate is pitched at marketing teams, but it&#x27;s developer tooling, and that&#x27;s fine. What would have to change, from someone who&#x27;s watched Kentico do it.]]></description>
                    <pubDate>Tue, 18 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/baryodev.umbraco.readaloud</guid>
                    <title>BaryoDev.Umbraco.ReadAloud</title>
                    <link>https://marketplace.umbraco.com/package/baryodev.umbraco.readaloud</link>
                    <description><![CDATA[Read this first: this uses the same free endpoint Microsoft Edge uses for its own read-aloud feature. It is not a supported Microsoft API and could change or stop working without notice. There is no paid provider in this version and no credentials are read anywhere; a site that needs a supported service registers its own engine. If the endpoint fails at runtime the browser client falls back to the speech synthesis built into every modern browser, so a page always has a voice. With that said: add &quot;listen to this article&quot; to any page with a single element. Audio is generated and cached on your own server, word highlighting follows real timings from the engine rather than estimates, and nothing about a listener is ever stored. No table, no migration, no IP, no user agent. Free and MIT licensed, with no build step and no third-party dashboard.]]></description>
                    <pubDate>Tue, 18 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://www.linkedin.com/pulse/what-back-office-tells-you-pitch-never-adam-shallcross-xrkpe/</guid>
                    <title>What the back office tells you that the pitch never will</title>
                    <link>https://www.linkedin.com/pulse/what-back-office-tells-you-pitch-never-adam-shallcross-xrkpe/</link>
                    <description><![CDATA[This is the first of these. Every week I will write about one specific way digital work drifts from what it was supposed to achieve, usually because of a decision made years earlier by someone who has since left.]]></description>
                    <pubDate>Tue, 18 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://umbraco.com/blog/security-advisory-aug-18-2026-security-patches-for-umbraco-cms-umbraco-forms-and-umbraco-ai-now-available/</guid>
                    <title>Security Advisory: Security Patches for Umbraco CMS,  Umbraco Forms, and Umbraco AI now available</title>
                    <link>https://umbraco.com/blog/security-advisory-aug-18-2026-security-patches-for-umbraco-cms-umbraco-forms-and-umbraco-ai-now-available/</link>
                    <description><![CDATA[Security patches for Umbraco CMS, Forms, and AI are now out. We recommend you to upgrade to the fixed versions.]]></description>
                    <pubDate>Tue, 18 Aug 2026 00:00:00 Z</pubDate>
                        <category>hq</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/lait.umbraco.gotocontent</guid>
                    <title>Lait.Umbraco.GoToContent</title>
                    <link>https://marketplace.umbraco.com/package/lait.umbraco.gotocontent</link>
                    <description><![CDATA[Adds a floating &quot;Edit in Umbraco&quot; pill to the top-right of your public pages, visible only to signed-in backoffice editors. One click jumps straight from the live page to the content editor for the node you&#x27;re viewing. Zero configuration &#x2014; just add the package.]]></description>
                    <pubDate>Tue, 18 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/esatto.umbraco.backoffice.mediatreedraganddrop</guid>
                    <title>Esatto.Umbraco.Backoffice.MediaTreeDragAndDrop</title>
                    <link>https://marketplace.umbraco.com/package/esatto.umbraco.backoffice.mediatreedraganddrop</link>
                    <description><![CDATA[Native HTML5 drag-and-drop for the Umbraco 17/18 backoffice Media tree. Adds three-zone (above / into / below) drop targets per row with optimistic same-parent reorder and full cross-parent move support. Pure App_Plugins package &#x2014; no C# code.]]></description>
                    <pubDate>Tue, 18 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/jumoo.translationmanager.csv</guid>
                    <title>Jumoo.TranslationManager.CSV</title>
                    <link>https://marketplace.umbraco.com/package/jumoo.translationmanager.csv</link>
                    <description><![CDATA[CSV File Connector for Translation Manager for Umbraco]]></description>
                    <pubDate>Tue, 18 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://github.com/limbo-works/Limbo.Umbraco.YouTube/releases/tag/v17.0.0-alpha001</guid>
                    <title>Limbo.Umbraco.YouTube 17.0.0-alpha001</title>
                    <link>https://github.com/limbo-works/Limbo.Umbraco.YouTube/releases/tag/v17.0.0-alpha001</link>
                    <description><![CDATA[Video picker for inserting YouTube videos in Umbraco.]]></description>
                    <pubDate>Mon, 17 Aug 2026 13:27:49 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.memberdashboard</guid>
                    <title>Umbraco.Community.MemberDashboard</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.memberdashboard</link>
                    <description><![CDATA[A backoffice dashboard for managing Umbraco members in bulk: filter by member group and approval/lockout status, sort and page through the whole member base, unlock / approve / unapprove / delete many members at once, and edit a member in a side panel.]]></description>
                    <pubDate>Sat, 15 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://github.com/limbo-works/Limbo.Umbraco.Fetch/releases/tag/v17.0.0-alpha001</guid>
                    <title>Limbo.Umbraco.Fetch 17.0.0-alpha001</title>
                    <link>https://github.com/limbo-works/Limbo.Umbraco.Fetch/releases/tag/v17.0.0-alpha001</link>
                    <description><![CDATA[Umbraco package for periodically downloading files to disk.]]></description>
                    <pubDate>Fri, 14 Aug 2026 11:32:48 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                </item>
                <item>
                    <guid>https://baryodev.medium.com/i-built-a-free-self-hosted-pwa-package-for-umbraco-because-the-alternative-bills-per-site-0f8ae279f98e?source=rss------umbraco-5</guid>
                    <title>I built a free, self-hosted PWA package for Umbraco, because the alternative bills per site</title>
                    <link>https://baryodev.medium.com/i-built-a-free-self-hosted-pwa-package-for-umbraco-because-the-alternative-bills-per-site-0f8ae279f98e?source=rss------umbraco-5</link>
                    <description><![CDATA[&lt;div class=&quot;medium-feed-item&quot;&gt;&lt;p class=&quot;medium-feed-image&quot;&gt;&lt;a href=&quot;https://baryodev.medium.com/i-built-a-free-self-hosted-pwa-package-for-umbraco-because-the-alternative-bills-per-site-0f8ae279f98e?source=rss------umbraco-5&quot;&gt;&lt;img src=&quot;https://cdn-images-1.medium.com/max/1400/0*EjatTe6pMaVpkNdy.png&quot; width=&quot;1400&quot;&gt;&lt;/a&gt;&lt;/p&gt;&lt;p class=&quot;medium-feed-snippet&quot;&gt;There are over 900 packages on the Umbraco Marketplace.&lt;/p&gt;&lt;p class=&quot;medium-feed-link&quot;&gt;&lt;a href=&quot;https://baryodev.medium.com/i-built-a-free-self-hosted-pwa-package-for-umbraco-because-the-alternative-bills-per-site-0f8ae279f98e?source=rss------umbraco-5&quot;&gt;Continue reading on Medium &#xBB;&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;]]></description>
                    <pubDate>Fri, 14 Aug 2026 09:59:54 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://baryodev.medium.com/i-built-a-free-self-hosted-pwa-package-for-umbraco-because-the-alternative-bills-per-site-0f8ae279f98e?source=rss-d15ca64e7255------2</guid>
                    <title>I built a free, self-hosted PWA package for Umbraco, because the alternative bills per site</title>
                    <link>https://baryodev.medium.com/i-built-a-free-self-hosted-pwa-package-for-umbraco-because-the-alternative-bills-per-site-0f8ae279f98e?source=rss-d15ca64e7255------2</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Fri, 14 Aug 2026 09:59:54 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://medium.com/@teamAaitek/who-is-watching-your-enterprise-cms-at-2-00-am-6f729c2fe87e?source=rss------umbraco-5</guid>
                    <title>Who is Watching Your Enterprise CMS at 2:00 AM?</title>
                    <link>https://medium.com/@teamAaitek/who-is-watching-your-enterprise-cms-at-2-00-am-6f729c2fe87e?source=rss------umbraco-5</link>
                    <description><![CDATA[&lt;div class=&quot;medium-feed-item&quot;&gt;&lt;p class=&quot;medium-feed-image&quot;&gt;&lt;a href=&quot;https://medium.com/@teamAaitek/who-is-watching-your-enterprise-cms-at-2-00-am-6f729c2fe87e?source=rss------umbraco-5&quot;&gt;&lt;img src=&quot;https://cdn-images-1.medium.com/max/1200/1*t_ol4gGWXP46uWIcvCN1gg.png&quot; width=&quot;1200&quot;&gt;&lt;/a&gt;&lt;/p&gt;&lt;p class=&quot;medium-feed-snippet&quot;&gt;For enterprise platforms running Sitecore, Strapi, or Umbraco, downtime isn&amp;#x2019;t just an inconvenience &amp;#x2014; it directly impacts revenue and&amp;#x2026;&lt;/p&gt;&lt;p class=&quot;medium-feed-link&quot;&gt;&lt;a href=&quot;https://medium.com/@teamAaitek/who-is-watching-your-enterprise-cms-at-2-00-am-6f729c2fe87e?source=rss------umbraco-5&quot;&gt;Continue reading on Medium &#xBB;&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;]]></description>
                    <pubDate>Fri, 14 Aug 2026 06:18:35 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://medium.com/@teamAaitek/is-technical-debt-slowing-down-your-sitecore-platform-905d74415f1a?source=rss------umbraco-5</guid>
                    <title>Is Technical Debt Slowing Down Your Sitecore Platform?</title>
                    <link>https://medium.com/@teamAaitek/is-technical-debt-slowing-down-your-sitecore-platform-905d74415f1a?source=rss------umbraco-5</link>
                    <description><![CDATA[&lt;div class=&quot;medium-feed-item&quot;&gt;&lt;p class=&quot;medium-feed-image&quot;&gt;&lt;a href=&quot;https://medium.com/@teamAaitek/is-technical-debt-slowing-down-your-sitecore-platform-905d74415f1a?source=rss------umbraco-5&quot;&gt;&lt;img src=&quot;https://cdn-images-1.medium.com/max/2600/1*qGaT170tcx6t1fu9Ymm9zQ.png&quot; width=&quot;3080&quot;&gt;&lt;/a&gt;&lt;/p&gt;&lt;p class=&quot;medium-feed-snippet&quot;&gt;Many enterprise organizations invest heavily in Sitecore, only to watch performance degrade and upgrade timelines stretch out indefinitely&amp;#x2026;&lt;/p&gt;&lt;p class=&quot;medium-feed-link&quot;&gt;&lt;a href=&quot;https://medium.com/@teamAaitek/is-technical-debt-slowing-down-your-sitecore-platform-905d74415f1a?source=rss------umbraco-5&quot;&gt;Continue reading on Medium &#xBB;&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;]]></description>
                    <pubDate>Fri, 14 Aug 2026 06:06:23 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/usync.umbraco.commerce</guid>
                    <title>uSync.Umbraco.Commerce</title>
                    <link>https://marketplace.umbraco.com/package/usync.umbraco.commerce</link>
                    <description><![CDATA[uSync serializers and handlers for Umbraco Commerce. Extends uSync so store settings &#x2014; stores, currencies, countries, regions, tax classes, shipping/payment methods, order statuses, and email/print/export templates &#x2014; export and import as config files, the same way uSync handles content types and the rest of the backoffice. Discounts and gift cards are supported too, opt-in.]]></description>
                    <pubDate>Fri, 14 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/baryodev.umbraco.pwa</guid>
                    <title>BaryoDev.Umbraco.Pwa</title>
                    <link>https://marketplace.umbraco.com/package/baryodev.umbraco.pwa</link>
                    <description><![CDATA[Turn an Umbraco site into an installable, offline-capable app, and see who installed it from the backoffice you are already signed into. Free and self-hosted: the install data lands in your own database and never leaves your server, so there is no third-party dashboard to log into and no processor to declare.]]></description>
                    <pubDate>Fri, 14 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://samsolutions.medium.com/what-is-umbraco-a-complete-guide-to-the-open-source-cms-14a24eaefe51?source=rss------umbraco-5</guid>
                    <title>What Is Umbraco? A Complete Guide to the Open-Source CMS</title>
                    <link>https://samsolutions.medium.com/what-is-umbraco-a-complete-guide-to-the-open-source-cms-14a24eaefe51?source=rss------umbraco-5</link>
                    <description><![CDATA[&lt;div class=&quot;medium-feed-item&quot;&gt;&lt;p class=&quot;medium-feed-image&quot;&gt;&lt;a href=&quot;https://samsolutions.medium.com/what-is-umbraco-a-complete-guide-to-the-open-source-cms-14a24eaefe51?source=rss------umbraco-5&quot;&gt;&lt;img src=&quot;https://cdn-images-1.medium.com/max/1672/1*GvkMBnti26YzRjKOr3B76g.png&quot; width=&quot;1672&quot;&gt;&lt;/a&gt;&lt;/p&gt;&lt;p class=&quot;medium-feed-snippet&quot;&gt;Some CMS platforms arrive with strong opinions about how a site should work. Umbraco leaves more of those decisions open.&lt;/p&gt;&lt;p class=&quot;medium-feed-link&quot;&gt;&lt;a href=&quot;https://samsolutions.medium.com/what-is-umbraco-a-complete-guide-to-the-open-source-cms-14a24eaefe51?source=rss------umbraco-5&quot;&gt;Continue reading on Medium &#xBB;&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;]]></description>
                    <pubDate>Thu, 13 Aug 2026 13:40:46 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://github.com/limbo-works/Limbo.Umbraco.TwentyThree/releases/tag/v17.0.0-alpha002</guid>
                    <title>Limbo.Umbraco.TwentyThree 17.0.0-alpha002</title>
                    <link>https://github.com/limbo-works/Limbo.Umbraco.TwentyThree/releases/tag/v17.0.0-alpha002</link>
                    <description><![CDATA[Video picker for inserting TwentyThree videos in Umbraco.]]></description>
                    <pubDate>Thu, 13 Aug 2026 08:48:01 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                </item>
                <item>
                    <guid>https://github.com/limbo-works/Limbo.Umbraco.Emply/releases/tag/v17.0.0-alpha001</guid>
                    <title>Limbo.Umbraco.Emply 17.0.0-alpha001</title>
                    <link>https://github.com/limbo-works/Limbo.Umbraco.Emply/releases/tag/v17.0.0-alpha001</link>
                    <description><![CDATA[Umbraco integration for the Emply API.]]></description>
                    <pubDate>Thu, 13 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                </item>
                <item>
                    <guid>https://umbraco.com/blog/security-heads-up-upcoming-security-patches-for-umbraco-cms-and-umbraco-forms-ready-on-august-18-2026-at-08-am-utc/</guid>
                    <title>Security Heads-Up: Upcoming Security Patches for Umbraco CMS and Umbraco Forms ready on August 18, 2026 at 08 AM UTC</title>
                    <link>https://umbraco.com/blog/security-heads-up-upcoming-security-patches-for-umbraco-cms-and-umbraco-forms-ready-on-august-18-2026-at-08-am-utc/</link>
                    <description><![CDATA[Heads-up: High-severity patches for Umbraco CMS, Forms, and AI arrive August 18, 2026, at 08 AM UTC. Prepare your systems for updates.]]></description>
                    <pubDate>Thu, 13 Aug 2026 00:00:00 Z</pubDate>
                        <category>hq</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/phases.umbraco.emojipicker</guid>
                    <title>Phases.Umbraco.EmojiPicker</title>
                    <link>https://marketplace.umbraco.com/package/phases.umbraco.emojipicker</link>
                    <description><![CDATA[Emoji Picker property editor and TipTap RTE toolbar button for inserting emoji at the caret. Compatible with Umbraco 17 and 18.]]></description>
                    <pubDate>Thu, 13 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/ucomments</guid>
                    <title>uComments</title>
                    <link>https://marketplace.umbraco.com/package/ucomments</link>
                    <description><![CDATA[Collaborative discussions, mentions and notifications directly inside the Umbraco backoffice.]]></description>
                    <pubDate>Thu, 13 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/phases.umbraco.charactercounter</guid>
                    <title>Phases.Umbraco.CharacterCounter</title>
                    <link>https://marketplace.umbraco.com/package/phases.umbraco.charactercounter</link>
                    <description><![CDATA[A Textbox-style property editor that shows a live character count while editors type, with soft warning and over-limit colors. Compatible with Umbraco 17 and 18.]]></description>
                    <pubDate>Thu, 13 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/utpro.feature.searchplus</guid>
                    <title>uTPro.Feature.SearchPlus</title>
                    <link>https://marketplace.umbraco.com/package/utpro.feature.searchplus</link>
                    <description><![CDATA[Enhance Umbraco site search with synonym expansion and diacritics-insensitive matching, managed from the backoffice. Users searching &#x27;laptop&#x27; will also find content containing &#x27;may tinh&#x27;, &#x27;pc&#x27;, or &#x27;computer&#x27;. Users searching without accents (&#x27;cong ty&#x27;) will find &#x27;cong ty&#x27;. Includes a backoffice UI under Settings for creating, editing and testing synonym groups. 25 common Vietnamese-English synonym groups are pre-loaded. Stores data in the Umbraco database (SQL Server, SQLite, PostgreSQL). Integrates automatically with uTPro.Extension.Search for zero-config query expansion. Also exposes an authenticated REST API for synonym CRUD and expansion testing.]]></description>
                    <pubDate>Wed, 12 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.datatypes.brazilstates</guid>
                    <title>SplatDev.Umbraco.DataTypes.BrazilStates</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.datatypes.brazilstates</link>
                    <description><![CDATA[A pre-configured Umbraco data type providing a dropdown of Brazil&#x27;s 27 federative units &#x2014; the 26 states plus the Distrito Federal. Values are stored in proper case with accents, as written in Portuguese. Umbraco 13 (net8.0) and 17 (net10.0); the data type installs itself on Umbraco 13.]]></description>
                    <pubDate>Wed, 12 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://www.youtube.com/watch?v=1jZbBy0p3hI</guid>
                    <title>Unlocking the Power of Umbraco&#x27;s Commercial Products</title>
                    <link>https://www.youtube.com/watch?v=1jZbBy0p3hI</link>
                    <description><![CDATA[An exciting Umbraco India User Group meetup with Corn&#xE9; Hoskam, Technical Team Lead for Commercial Products at Umbraco and former Umbraco MVP &#x1F929;]]></description>
                    <pubDate>Tue, 11 Aug 2026 15:03:20 Z</pubDate>
                        <category>community</category>
                        <category>youtube</category>
                </item>
                <item>
                    <guid>https://github.com/abjerner/Limbo.Umbraco.Iddqd/releases/tag/v17.0.0-alpha001</guid>
                    <title>Limbo.Umbraco.Iddqd 17.0.0-alpha001</title>
                    <link>https://github.com/abjerner/Limbo.Umbraco.Iddqd/releases/tag/v17.0.0-alpha001</link>
                    <description><![CDATA[Limbo.Umbraco.Iddqd package with various developer oriented improvements for the Umbraco backoffice.]]></description>
                    <pubDate>Tue, 11 Aug 2026 13:36:41 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                </item>
                <item>
                    <guid>https://github.com/limbo-works/Limbo.Umbraco.ModelsBuilder/releases/tag/v17.0.0-alpha002</guid>
                    <title>Limbo.Umbraco.ModelsBuilder 17.0.0-alpha002</title>
                    <link>https://github.com/limbo-works/Limbo.Umbraco.ModelsBuilder/releases/tag/v17.0.0-alpha002</link>
                    <description><![CDATA[Limbo.Umbraco.ModelsBuilder is a custom models builder for Umbraco that provides extended functionality compared to Umbraco&#x27;s build-in models builder.]]></description>
                    <pubDate>Tue, 11 Aug 2026 09:25:42 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                </item>
                <item>
                    <guid>https://github.com/limbo-works/Limbo.Umbraco.MediaPicker/releases/tag/v17.0.0-alpha001</guid>
                    <title>Limbo.Umbraco.MediaPicker 17.0.0-alpha001</title>
                    <link>https://github.com/limbo-works/Limbo.Umbraco.MediaPicker/releases/tag/v17.0.0-alpha001</link>
                    <description><![CDATA[Umbraco package that extends the functionality of Umbraco&#x27;s build-in media picker property editor.]]></description>
                    <pubDate>Tue, 11 Aug 2026 09:07:24 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.themes.landing</guid>
                    <title>SplatDev.Umbraco.Themes.Landing</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.themes.landing</link>
                    <description><![CDATA[Landing page theme for Umbraco - hero section, features grid, testimonials, pricing cards, FAQ accordion, CTA banner]]></description>
                    <pubDate>Tue, 11 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.npoco</guid>
                    <title>SplatDev.Umbraco.NPoco</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.npoco</link>
                    <description><![CDATA[NPoco database layer extensions for Umbraco 13 (net8.0) and Umbraco 17 (net10.0)]]></description>
                    <pubDate>Tue, 11 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.tools.packageactions</guid>
                    <title>SplatDev.Umbraco.Tools.PackageActions</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.tools.packageactions</link>
                    <description><![CDATA[Umbraco package action helpers &#x2014; run document type, data type, template and content node setup during package install.]]></description>
                    <pubDate>Tue, 11 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.examine</guid>
                    <title>SplatDev.Umbraco.Examine</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.examine</link>
                    <description><![CDATA[Examine/Lucene search extensions for Umbraco 13 (net8.0) and Umbraco 17 (net10.0)]]></description>
                    <pubDate>Tue, 11 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.themes.hotel</guid>
                    <title>SplatDev.Umbraco.Themes.Hotel</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.themes.hotel</link>
                    <description><![CDATA[Hotel/hospitality theme for Umbraco - rooms, booking, gallery, amenities, reviews, location map]]></description>
                    <pubDate>Tue, 11 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.themes.corporate</guid>
                    <title>SplatDev.Umbraco.Themes.Corporate</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.themes.corporate</link>
                    <description><![CDATA[Professional corporate theme for Umbraco - home, about, services, team, contact pages]]></description>
                    <pubDate>Tue, 11 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.themes.base</guid>
                    <title>SplatDev.Umbraco.Themes.Base</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.themes.base</link>
                    <description><![CDATA[Umbraco Base Theme - Foundation theme with reusable components: navigation, footer, sidebar, responsive grid. Required by all other UmbracoCms themes.]]></description>
                    <pubDate>Tue, 11 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.datatypes.usstates</guid>
                    <title>SplatDev.Umbraco.DataTypes.USStates</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.datatypes.usstates</link>
                    <description><![CDATA[US States data type for Umbraco 13 (net8.0) and Umbraco 17 (net10.0)]]></description>
                    <pubDate>Tue, 11 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/foxcart.template.chakra</guid>
                    <title>FoxCart.Template.Chakra</title>
                    <link>https://marketplace.umbraco.com/package/foxcart.template.chakra</link>
                    <description><![CDATA[Chakra design template for FoxCart: everything radiates from a centre. A concentric ring field wraps a circular product frame, deep full-bleed colour bands carry the weight of the page, and one accent colour only ever means &#x201C;act here&#x201D;. Calm pacing and wide air, suited to wellness, holistic and lifestyle catalogues. Ships 4 presets (Tachyon, Aura, Lightspeed and Eclipse, the last dark-only), complete page views (home, shop, product with variants and extra fields, cart, multi-step checkout, order confirmation, blog and content pages) and optional FoxCart Members view overrides. Installs a walkable store in one restart on top of FoxCart Template.]]></description>
                    <pubDate>Tue, 11 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.themes.blog</guid>
                    <title>SplatDev.Umbraco.Themes.Blog</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.themes.blog</link>
                    <description><![CDATA[Blog theme for Umbraco - post layout, author bio, comment section, categories sidebar, archive page]]></description>
                    <pubDate>Tue, 11 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.themes.conference</guid>
                    <title>SplatDev.Umbraco.Themes.Conference</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.themes.conference</link>
                    <description><![CDATA[Conference/event theme for Umbraco - schedule, speakers, venue, registration, countdown]]></description>
                    <pubDate>Tue, 11 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.themes.commerce</guid>
                    <title>SplatDev.Umbraco.Themes.Commerce</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.themes.commerce</link>
                    <description><![CDATA[E-commerce theme for Umbraco - product grid, product detail, cart, checkout, category browse]]></description>
                    <pubDate>Tue, 11 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.entityframework</guid>
                    <title>SplatDev.Umbraco.EntityFramework</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.entityframework</link>
                    <description><![CDATA[Entity Framework Core integration for Umbraco 13 (net8.0) and Umbraco 17 (net10.0)]]></description>
                    <pubDate>Tue, 11 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.pdfcurator</guid>
                    <title>SplatDev.Umbraco.Plugins.PdfCurator</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.pdfcurator</link>
                    <description><![CDATA[Book Library backoffice section for Umbraco 17. Dashboard, library browser, review queue, and reports for managing PDF digital books and documents. Pluggable Lit web component architecture ready for the full PdfCurator component suite. Supports Umbraco 13 (net8.0) and Umbraco 17 (net10.0).]]></description>
                    <pubDate>Tue, 11 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/foxcart.template.grid</guid>
                    <title>FoxCart.Template.Grid</title>
                    <link>https://marketplace.umbraco.com/package/foxcart.template.grid</link>
                    <description><![CDATA[Grid design template for FoxCart: commerce presented like a magazine spread. Oversized display type, an asymmetric layout primitive, and a rotated hard-shadow stamp that recurs on prices, badges and buttons. Ships 4 presets (Studio, Noir &#x2014; dark-only &#x2014;, Riot and Heritage, each moving type, border weight and motion rather than colour alone), complete page views (home, shop, product with variants and extra fields, cart, multi-step checkout, order confirmation, blog and content pages) and optional FoxCart Members view overrides. Installs a walkable store in one restart on top of FoxCart Template.]]></description>
                    <pubDate>Tue, 11 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/skybrud.umbraco.redirects.automate</guid>
                    <title>Skybrud.Umbraco.Redirects.Automate</title>
                    <link>https://marketplace.umbraco.com/package/skybrud.umbraco.redirects.automate</link>
                    <description><![CDATA[Automate addon for Skybrud Redirects.]]></description>
                    <pubDate>Tue, 11 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/foxcart.template.lean</guid>
                    <title>FoxCart.Template.Lean</title>
                    <link>https://marketplace.umbraco.com/package/foxcart.template.lean</link>
                    <description><![CDATA[Lean design template for FoxCart: a clean, hard-cut storefront design with 10 selectable themes, complete page views (home, shop, product with variants and extra fields, cart, multi-step checkout, order confirmation, blog and content pages) and optional FoxCart Members view overrides. Installs a walkable store in one restart on top of FoxCart Template.]]></description>
                    <pubDate>Tue, 11 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/foxcart.template</guid>
                    <title>FoxCart.Template</title>
                    <link>https://marketplace.umbraco.com/package/foxcart.template</link>
                    <description><![CDATA[Template addon base for FoxCart: seeds the shared website/shop content model (Home, Shop, Product with variants and extra fields, Cart, Checkout, Order Confirmation, Content Page, Articles) with its Block List element types, plus a backoffice store installer and shared cart/checkout surface controllers. Design-agnostic &#x2014; install a design package (Lean, Clarity, Flow, Grid or Chakra) for the actual views and styling.]]></description>
                    <pubDate>Tue, 11 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/foxcart.template.clarity</guid>
                    <title>FoxCart.Template.Clarity</title>
                    <link>https://marketplace.umbraco.com/package/foxcart.template.clarity</link>
                    <description><![CDATA[Accessibility-first design template for FoxCart, built to WCAG 2.2: visible focus design language, fieldset-based forms, nothing conveyed by colour alone. Ships 4 selectable themes (Standard, Contrast, Dusk, Sage), complete page views (home, shop, product with variants and extra fields, cart, multi-step checkout, order confirmation, blog and content pages) and optional FoxCart Members view overrides. Installs a walkable store in one restart on top of FoxCart Template.]]></description>
                    <pubDate>Tue, 11 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/foxcart.template.flow</guid>
                    <title>FoxCart.Template.Flow</title>
                    <link>https://marketplace.umbraco.com/package/foxcart.template.flow</link>
                    <description><![CDATA[Flow design template for FoxCart: the soft counter-thesis to Lean &#x2014; nothing is cut, everything blends. A floating pill nav with an inline search field, gradient-blob decoration, wave-shaped section dividers, and product media clipped organically with a price pill that overlaps the edge. Ships 6 presets (Standard, Smoke, Ocean, Bloom, Citrus and Aurora, the last dark-only), complete page views (home, shop, product with variants and extra fields, cart, multi-step checkout, order confirmation, blog and content pages) and optional FoxCart Members view overrides. Installs a walkable store in one restart on top of FoxCart Template.]]></description>
                    <pubDate>Tue, 11 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.defaultvalue</guid>
                    <title>SplatDev.Umbraco.Plugins.DefaultValue</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.defaultvalue</link>
                    <description><![CDATA[Set default values for Umbraco content properties by document type and property alias. Automatically populate properties when new content nodes are created. Supports Umbraco 13 (net8.0) and Umbraco 17 (net10.0).]]></description>
                    <pubDate>Tue, 11 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.copyvalue</guid>
                    <title>SplatDev.Umbraco.Plugins.CopyValue</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.copyvalue</link>
                    <description><![CDATA[Copy property values between Umbraco content nodes &#x2014; bulk copy, property mapping between different document types, and reusable mapping templates. Supports Umbraco 13 (net8.0) and Umbraco 17 (net10.0).]]></description>
                    <pubDate>Tue, 11 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.backups</guid>
                    <title>SplatDev.Umbraco.Plugins.Backups</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.backups</link>
                    <description><![CDATA[Create, schedule, and restore Umbraco backups directly from the backoffice. Supports 10&#x2B; cloud storage providers: Azure Blob, Amazon S3, Dropbox, Google Drive, OneDrive, Box, Mega, Seafile, SFTP, and local file system. Backup retention policies, email notifications, and CRON-based scheduling built in. Supports Umbraco 13 (net8.0) and Umbraco 17 (net10.0).]]></description>
                    <pubDate>Tue, 11 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.authorization.ldap</guid>
                    <title>SplatDev.Umbraco.Authorization.Ldap</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.authorization.ldap</link>
                    <description><![CDATA[LDAP/Active Directory SSO authentication for Umbraco 13 (net8.0) and Umbraco 17 (net10.0)]]></description>
                    <pubDate>Tue, 11 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.nugetcatalog</guid>
                    <title>SplatDev.Umbraco.Plugins.NuGetCatalog</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.nugetcatalog</link>
                    <description><![CDATA[Backoffice dashboard listing the packages you publish to nuget.org &#x2014; download counts, latest version and a short summary per package. Add specific packages by URL, hide the ones you don&#x27;t care about. Umbraco 17 (net10.0).]]></description>
                    <pubDate>Tue, 11 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://www.dynamicdave.nl/blog/an-unexpected-reflection/</guid>
                    <title>I&#x27;ve used Umbraco for more than a decade. An unexpected reflection.</title>
                    <link>https://www.dynamicdave.nl/blog/an-unexpected-reflection/</link>
                    <description><![CDATA[I just got back from vacation, and, for the first time in ages, I managed to ditch my laptop. So no Visual Studio, no migrations and no coding whatsoever. No people asking me &#x201C;can you just&#x2026;?&#x201D;. It felt pretty good to unplug for a bit. I wasn&#x2019;t mentally writing code the whole time, and I definitely didn&#x2019;t set out to think about Umbraco over my morning coffee.And I was planning on reading blog posts, listen to a few podcasts, reading the docs, etc. But the terrible mobile connection in France prevented that. So I kicked back, soaked up some sun, and enjoyed the joy of doing nothing productive (and a beer here of there), my mind wandered back to it anyway. Because this holiday made me look back and reflect at the last couple of years somehow. Maybe it was the lack of a laptop that made me a look back&#x2026;I&#x2019;ve been working with Umbraco for 10&#x2B; years now. I started somewhere around 2012 or 2013, with Umbraco 4. In that time, I&#x2019;ve watched versions come and go, seen the platform shift in big ways, and watched the community explode to what it is today. And I&#x2019;ve wrangled my way through more projects and upgrades than I care to count.Thinking about that is weird. I never expected, back when I started, that I&#x2019;d still be talking about Umbraco a decade later. It became part of my career, a source of major learning, and eventually even something I started writing about.So while I was taking a break, I found myself reflecting on this whole adventure. Not just on the version numbers, but on how the platform changed&#x2014;and, honestly, how I changed right alongside it.]]></description>
                    <pubDate>Mon, 10 Aug 2026 22:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://github.com/skybrud/Skybrud.Umbraco.Redirects.Automate/releases/tag/v17.0.0</guid>
                    <title>Skybrud.Umbraco.Redirects.Automate 17.0.0</title>
                    <link>https://github.com/skybrud/Skybrud.Umbraco.Redirects.Automate/releases/tag/v17.0.0</link>
                    <description><![CDATA[Automate addon for Skybrud Redirects.]]></description>
                    <pubDate>Mon, 10 Aug 2026 16:35:32 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                </item>
                <item>
                    <guid>https://umbracocommunity.social/@umbraco/117070178598499388</guid>
                    <title>Codegarden 2026 talks are officially live on YouTube!</title>
                    <link>https://umbracocommunity.social/@umbraco/117070178598499388</link>
                    <description><![CDATA[&#x1F37F; Codegarden 2026 talks are officially live on YouTube!Missed a session? Want to revisit a mind-blowing talk? Or maybe you just want to experience the magic all over again?Stream the full lineup here &#x1F449; https://umbra.co/4xipSdAHappy watching! &#x1F499;#Umbraco]]></description>
                    <pubDate>Mon, 10 Aug 2026 09:41:00 Z</pubDate>
                        <category>hq</category>
                        <category>mastodon</category>
                        <category>social</category>
                </item>
                <item>
                    <guid>https://www.youtube.com/watch?v=hTgwqcfITqM</guid>
                    <title>Jen Wolke, Cooking Up Quality with Chef Claude</title>
                    <link>https://www.youtube.com/watch?v=hTgwqcfITqM</link>
                    <description><![CDATA[AI isn&#x27;t just for building things &#x2014; it&#x27;s for breaking them better, too. In this session, we&#x27;ll move beyond the usual AI hype and explore how Claude Chat on the Desktop and the Claude browser extension can become your secret weapons for smarter, faster QA. Think fewer missed bugs, tighter feedback loops, and a testing workflow that actually keeps pace with your team.]]></description>
                    <pubDate>Mon, 10 Aug 2026 08:25:02 Z</pubDate>
                        <category>hq</category>
                        <category>youtube</category>
                </item>
                <item>
                    <guid>https://www.youtube.com/watch?v=Fjk8iMfPdeE</guid>
                    <title>Matthew Wise, Vibe Coder to AI Engineer</title>
                    <link>https://www.youtube.com/watch?v=Fjk8iMfPdeE</link>
                    <description><![CDATA[From Designs to Umbraco (and Everything In Between)&#xA;A refreshingly honest journey through AI-assisted development &#x2014; going from designs to a fully CMS-managed Umbraco experience using Claude Code and context engineering. Starting as a vibe coder throwing prompts and hoping for the best, and ending up with a real workflow that actually delivers.&#xA;&#xA;What You&#x27;ll See Through real recordings and demonstrations:&#xA;&#xA;- Building Umbraco document types, compositions, and content with Claude Code&#xA;- Context engineering techniques &#x2014; planning, memories, and knowing when the AI needs a firm talking-to&#xA;- MCP servers and sub-agents (when they cooperate)&#xA;- Custom commands and skills that turned hours of work into minutes&#xA;&#xA;The Real Talk&#xA;This isn&#x27;t a highlight reel. Expect moments where Claude gets creative in unexpected ways, prompts go sideways, and the classic &quot;it works on my machine&quot; makes an appearance. That&#x27;s where the real learning happens.&#xA;&#xA;Perfect for developers ready to embrace AI workflows &#x2014; complete with the beautiful chaos.]]></description>
                    <pubDate>Mon, 10 Aug 2026 06:00:39 Z</pubDate>
                        <category>hq</category>
                        <category>youtube</category>
                </item>
                <item>
                    <guid>https://www.youtube.com/watch?v=JNAmfCsVmBY</guid>
                    <title>Nikolaj Hjelm Kaplan, Anne Pehrson &amp; Victor Nellemann, Inside the Danish Broadcasting News Platform</title>
                    <link>https://www.youtube.com/watch?v=JNAmfCsVmBY</link>
                    <description><![CDATA[Inside the Danish Broadcasting Corporation News Platform: Scaling Umbraco for 24/7 News&#xA;&#xA;When your CMS powers the daily work of several hundred journalists and publishes content to 9 out of 10 Danes, standard is never enough.&#xA;&#xA;The Danish Broadcasting Corporation rebuilt its mission-critical article CMS on Umbraco to replace a Drupal 7 platform approaching end-of-life. The result is a highly customised, high-performance editorial system that runs around the clock.&#xA;&#xA;In this session, you will see:&#xA;&#xA;- The overall architecture around Umbraco and how it integrates into DR&#x2019;s digital ecosystem&#xA;- How performance and stability are ensured in a 24/7 news cycle&#xA;- How a standard Umbraco installation was extended into a fully customised editorial platform&#xA;- Key backoffice customisations that support high-volume publishing with short turnaround times&#xA;- Lessons learned from migrating from Drupal 7 in a high-pressure environment&#xA;&#xA;This is a real-world enterprise implementation at national scale, with concrete architectural decisions, trade-offs, and practical insights you can take home.]]></description>
                    <pubDate>Mon, 10 Aug 2026 06:00:38 Z</pubDate>
                        <category>hq</category>
                        <category>youtube</category>
                </item>
                <item>
                    <guid>https://www.youtube.com/watch?v=4I_F5QJkvGE</guid>
                    <title>Lasse Fredslund, Rasmus John Pedersen, Umbraco Compose</title>
                    <link>https://www.youtube.com/watch?v=4I_F5QJkvGE</link>
                    <description><![CDATA[Come along for a deep technical tour through Umbraco Compose. Members of the product team will show off how it aggregates and combines data from multiple sources. Expect to see demos, tips, and loads of other technical insight into the platform!]]></description>
                    <pubDate>Mon, 10 Aug 2026 06:00:36 Z</pubDate>
                        <category>hq</category>
                        <category>youtube</category>
                </item>
                <item>
                    <guid>https://www.youtube.com/watch?v=KnfwRfpD5V8</guid>
                    <title>Owain Williams, Unlocking the Umbraco Management API Beyond the Backoffice</title>
                    <link>https://www.youtube.com/watch?v=KnfwRfpD5V8</link>
                    <description><![CDATA[The Umbraco backoffice runs on the Management API but what if you could harness that same power outside the CMS? Now you can.&#xA;&#xA;In this session, we&#x2019;ll cut through the jungle of Swagger docs together, surfacing hidden tips, decoding tricky payloads, and navigating the pain points so you don&#x2019;t have to. You&#x2019;ll see how to move beyond documentation into practical, real-world usage: integrating with external systems, extending functionality, and pushing the limits of what&#x2019;s possible with Umbraco.&#xA;&#xA;Expect plenty of hands-on advice, &#x201C;gotchas&#x201D; to avoid, and fresh inspiration for your own projects. You&#x2019;ll walk away confident to start building with the Management API &#x2014; and with new ideas on how it can transform the way you work with Umbraco.]]></description>
                    <pubDate>Mon, 10 Aug 2026 06:00:35 Z</pubDate>
                        <category>hq</category>
                        <category>youtube</category>
                </item>
                <item>
                    <guid>https://www.youtube.com/watch?v=hqCfrgQP-4M</guid>
                    <title>Kyle Brigham, The Future Is AI Search: Designing Umbraco for AEO and AI Discovery</title>
                    <link>https://www.youtube.com/watch?v=hqCfrgQP-4M</link>
                    <description><![CDATA[The &quot;Blue Link&quot; era is fading, and if you&#x27;re still building Umbraco sites solely for Google&#x2019;s first page, you&#x2019;re already behind. Today, we aren&#x27;t just optimizing for clicks; we&#x2019;re optimizing for answers.&#xA;&#xA;In this session, we&#x2019;ll move beyond the standard metadata fields and explore how the rise of Answer Engine Optimization (AEO) and AI Discovery is fundamentally changing the way we architect the backoffice and how we approach site content. &#xA;&#xA;In this session, we&#x27;ll dive into:&#xA;&#xA;- Why Search is now an ecosystem, not a destination.&#xA;- How to evolve website structure to support Large Language Models (LLMs) and AI overviews. &#xA;- Why a solid content strategy beats a &quot;magic SEO plugin&quot; every time.]]></description>
                    <pubDate>Mon, 10 Aug 2026 06:00:33 Z</pubDate>
                        <category>hq</category>
                        <category>youtube</category>
                </item>
                <item>
                    <guid>https://www.youtube.com/watch?v=Wk2c36P9SJw</guid>
                    <title>Jordan McFarlane, Umbraco Compose: What is this whole orchestration thing anyway</title>
                    <link>https://www.youtube.com/watch?v=Wk2c36P9SJw</link>
                    <description><![CDATA[Gone are the days where your website was backed by a CMS alone. It&#x27;s becoming increasingly common to power it with any number of three-letter acronyms - a PIM, a DAM, or even an ERP. You&#x27;ve probably got a search provider, maybe a marketing suite, and who knows what other systems that need their say in the experiences that you create for your customers.&#xA;&#xA;It&#x27;s a whole lot of technology, and a whole lot of effort to get each one talking with the others.&#xA;&#xA;Enter Umbraco Compose; a content orchestration platform that makes it easy to coordinate the flow of content between your backend systems and delivery channels.&#xA;&#xA;This talk will go into more detail about what this whole orchestration concept means, without getting too technical. You&#x27;ll hear more about typical challenges for content authors and business users that arise from bespoke solutions, and you&#x27;ll see how Compose can let you breeze right past them. You&#x27;ll get insight into what makes Compose a good fit for your project and learn all about what to expect from the product in future.]]></description>
                    <pubDate>Mon, 10 Aug 2026 06:00:31 Z</pubDate>
                        <category>hq</category>
                        <category>youtube</category>
                </item>
                <item>
                    <guid>https://www.youtube.com/watch?v=gE3WagFkWq8</guid>
                    <title>Matt Sutherland &amp; Georgina Bidder, A Website, an Email, and an AI Summary walk into a Bar&#x2026;</title>
                    <link>https://www.youtube.com/watch?v=gE3WagFkWq8</link>
                    <description><![CDATA[Creating and updating your website should be the least of your worries. With Umbraco, you get a content management system known and loved for its flexibility and great editing experience.&#xA;&#xA;Umbraco is easy to get started with install, set up, and host it yourself or let us take care of it all for you on Umbraco Cloud. https://try.umbraco.com&#xA;&#xA;Learn more about Umbraco on our website https://umbraco.com&#xA;Discover our Umbraco Community: https://community.umbraco.com/&#xA;Find the Umbraco source code on Github: https://github.com/umbraco/Umbraco-CMS&#xA;Visit the Umbraco Documentation: https://docs.umbraco.com]]></description>
                    <pubDate>Mon, 10 Aug 2026 06:00:30 Z</pubDate>
                        <category>hq</category>
                        <category>youtube</category>
                </item>
                <item>
                    <guid>https://www.youtube.com/watch?v=hHnG3WgAfmA</guid>
                    <title>Joe Glombek , Developers, Assemble! Community is Your Team&#x2019;s Superpower</title>
                    <link>https://www.youtube.com/watch?v=hHnG3WgAfmA</link>
                    <description><![CDATA[What happens when your team spends work time eating pizza and hanging out with other techies? Surprisingly, they don&#x2019;t just come back with stickers. They come back with ideas, solutions to problems, and a renewed enthusiasm for the work in front of them.&#xA;&#xA;The Umbraco community is one of the most active in the tech world, with in-person and virtual meetups across the globe hosting experts who love sharing their knowledge. For businesses, these events are an incredibly cost&#x2011;effective way to keep teams engaged and learning. While conferences or formal training can swallow days of time and thousands in cash, a local meetup costs little more than a couple of hours and a bus fare &#x2014; yet often delivers insights that save development time, reduce risk, keep technical debt in check and help teams adopt new technologies sooner while avoiding outdated approaches and reinventing the wheel.&#xA;&#xA;In this lightning talk, Joe shares what he&#x2019;s learned as an organiser of the Bristol Umbraco Meetup &#x2014; one of the longest&#x2011;running and best&#x2011;attended groups in the community.&#xA;&#xA;If you want a stronger tech team and bulletproof projects, helping them engage with the community might just be the highest-value superpower you can give them.]]></description>
                    <pubDate>Mon, 10 Aug 2026 06:00:30 Z</pubDate>
                        <category>hq</category>
                        <category>youtube</category>
                </item>
                <item>
                    <guid>https://www.youtube.com/watch?v=E3z8Wevmx_Q</guid>
                    <title>Markus Johansson, Hybrid Cache changes everything</title>
                    <link>https://www.youtube.com/watch?v=E3z8Wevmx_Q</link>
                    <description><![CDATA[When Umbraco introduced the new Hybrid Cache, it fundamentally changed the way that content is cached. It opens up new possibilities, but it also means that developers need to work differently when interacting with the published content of Umbraco. In this talk, we&#x27;ll explore what Hybrid Cache is, why it was introduced, how it improves performance, and what developers need to keep in mind when building solutions on top of it.]]></description>
                    <pubDate>Mon, 10 Aug 2026 06:00:30 Z</pubDate>
                        <category>hq</category>
                        <category>youtube</category>
                </item>
                <item>
                    <guid>https://www.youtube.com/watch?v=62LsHq_75PE</guid>
                    <title>Amalie Wowern, Commercial Products: What we&#x27;ve built and what&#x27;s next</title>
                    <link>https://www.youtube.com/watch?v=62LsHq_75PE</link>
                    <description><![CDATA[Update on the roadmap for Engage, Commerce, Workflow, Forms, UI Builder, and Deploy. What has happened this year, and what does the future bring.]]></description>
                    <pubDate>Mon, 10 Aug 2026 06:00:28 Z</pubDate>
                        <category>hq</category>
                        <category>youtube</category>
                </item>
                <item>
                    <guid>https://www.youtube.com/watch?v=QE9sIqk6w4s</guid>
                    <title>Tobias Jensen, Consolidating Multi-Country Marketing on Umbraco Cloud</title>
                    <link>https://www.youtube.com/watch?v=QE9sIqk6w4s</link>
                    <description><![CDATA[How do you move from scattered country websites and inconsistent messaging to one scalable global platform?&#xA;&#xA;In this case study, we explore how Orifarm unified multiple local market sites into a single Umbraco Cloud Baseline setup&#x2014;creating a strong global foundation while preserving the flexibility each market needs to succeed.&#xA;&#xA;Over time, independent country websites had evolved in different directions. Design systems varied, content structures diverged, and shared features were rebuilt again and again. The result was increasing complexity, inconsistent branding, and limited scalability. Orifarm needed a platform that could strengthen brand consistency, improve efficiency, and support future growth across markets.&#xA;&#xA;The ambition was clear: build once, reuse globally, and enable locally. The Umbraco Cloud Baseline became the technical and governance framework that made this possible. A shared codebase, standardized components, and defined global guidelines ensured consistency, while flexible content models and local configurations empowered markets to adapt messaging and campaigns to their needs.&#xA;&#xA;In this session, we share the business drivers behind the transformation, the architectural principles that shaped the solution, and the governance model that keeps it sustainable. We&#x2019;ll also openly discuss the mistakes we made along the way&#x2014;and the lessons learned&#x2014;so you can avoid the same pitfalls when building your own global platform.]]></description>
                    <pubDate>Mon, 10 Aug 2026 06:00:25 Z</pubDate>
                        <category>hq</category>
                        <category>youtube</category>
                </item>
                <item>
                    <guid>https://www.youtube.com/watch?v=QoMF-zeFQSc</guid>
                    <title>Daniel Horn, Migrating Three Large Websites Built on Kentico, WordPress and Webflow into One Umbraco</title>
                    <link>https://www.youtube.com/watch?v=QoMF-zeFQSc</link>
                    <description><![CDATA[Three large websites built on Kentico, WordPress, and Webflow were brought together into a single Umbraco platform for a global student organisation. Working through this consolidation highlighted a set of technical and editorial lessons that many Umbraco teams will recognise.&#xA;&#xA;Managing multiple CMS platforms in parallel led to repeated content updates, uneven structure, and editors switching between different tools. Over time, this increased coordination effort and made everyday maintenance harder than it needed to be.&#xA;&#xA;After reviewing the existing platforms, Umbraco was chosen based on its use of the .NET framework, alignment with Microsoft technology, Azure hosting support, EU hosting needs, and security requirements. Migrating more than five thousand pages brought up very practical questions around content modelling, field mapping, and deciding which content was still worth moving forward.&#xA;&#xA;Editor habits played an important role in several decisions. Many editors were coming from WordPress, where visual editing and drag based tools are familiar. The Umbraco editing experience felt different at first, so grid based editing and structured visual controls were introduced to help editors understand page layout while working. At the same time, features that felt unnecessary or cluttered in earlier tools were intentionally left out.&#xA;&#xA;The work also included referencing external data from SharePoint without duplicating it inside Umbraco, along with custom packages to support migration and editing needs.&#xA;&#xA;The talk focuses on lessons that Umbraco developers and architects can take into their own work when consolidating websites, handling large content sets, and supporting editors with different backgrounds.]]></description>
                    <pubDate>Mon, 10 Aug 2026 06:00:25 Z</pubDate>
                        <category>hq</category>
                        <category>youtube</category>
                </item>
                <item>
                    <guid>https://www.youtube.com/watch?v=-r4WlVvOwvw</guid>
                    <title>Becks Willis, Why most digital platforms struggle to justify their existence</title>
                    <link>https://www.youtube.com/watch?v=-r4WlVvOwvw</link>
                    <description><![CDATA[Most digital platforms are built with good intentions: better content, more flexibility, stronger performance, future-proofing. Teams work hard, launches go well, and early results often look positive.&#xA;&#xA;And yet, a few months later, many organisations struggle to answer a simple question: was this actually worth it?&#xA;&#xA;This talk explores why so many digital platforms become difficult to defend over time. Mainly because we never agree upfront how we&#x2019;ll know if they&#x2019;ve succeeded. So many sites and platforms are commissioned on ambition, but judged on dashboards and stats - with often the two being misaligned. &#xA;&#xA;Having been a performance marketing agency, when Hewitt Matthews bought tech agency, Quba, we needed to understand how these two services knit neatly together, and soon realised how few people get this right. With that in mind, I want to draw on the experience we gain from sitting in this middle pinch point. &#xA;&#xA;It&#x27;s not meant to be a case study or a &quot;how to&quot; session, but more of a talk on how we think about value, accountability and logenvity - and be a prompt for agencies and in-house teams to be more honest about what they&#x27;re budding and why. That being said, I&#x27;ll likely be talking about Umbraco Engage and how it serves as the gateway product between our performance business and our dev agency.&#xA;&#xA;If I nail this talk, people will leave with clearer questions to ask before the build so platforms are easier to defend later down the line.]]></description>
                    <pubDate>Mon, 10 Aug 2026 06:00:24 Z</pubDate>
                        <category>hq</category>
                        <category>youtube</category>
                </item>
                <item>
                    <guid>https://www.youtube.com/watch?v=gtK7gFXbfYg</guid>
                    <title>Rachel Breeze, Umbraco Decisions Stay, Upgrade, Rewrite</title>
                    <link>https://www.youtube.com/watch?v=gtK7gFXbfYg</link>
                    <description><![CDATA[With Umbraco 17 now available, the temptation to upgrade can be strong after all, it has new features and new performance gains, but upgrading isn&#x27;t always the right choice, and sticking with your current version isn&#x27;t always the wrong one. Every Umbraco project lives in its own reality. Each project has its own budgets, integrations, risk tolerance, developer capacity, and long-term business goals, all of which shape what &quot;the right path&quot; looks like.&#xA;In this talk, we&#x27;ll explore the full spectrum of options for maintaining an Umbraco site, from staying on the project&#x27;s current major version to upgrading thoughtfully or even rewriting when it truly makes sense.]]></description>
                    <pubDate>Mon, 10 Aug 2026 06:00:24 Z</pubDate>
                        <category>hq</category>
                        <category>youtube</category>
                </item>
                <item>
                    <guid>https://www.youtube.com/watch?v=b9mD8Xcge9o</guid>
                    <title>Martin Saaby, Composable B2B &#x2013; Why One of Denmark&#x2019;s Leading Wine Companies Chose Umbraco Compose</title>
                    <link>https://www.youtube.com/watch?v=b9mD8Xcge9o</link>
                    <description><![CDATA[Martin Saaby is Business Advisor &amp; Client Lead at Umbraco Platinum Partner Ecreo. With a background in international marketing and extensive experience in business development, he bridges strategy, data and technology. With deep expertise in Umbraco, he advises larger B2B companies on their digital platforms and helps them choose the right foundation for efficient scaling and sustainable competitive growth.]]></description>
                    <pubDate>Mon, 10 Aug 2026 06:00:23 Z</pubDate>
                        <category>hq</category>
                        <category>youtube</category>
                </item>
                <item>
                    <guid>https://umbraco.com/blog/uprofile-august-2026-gia-matikainen/</guid>
                    <title>uProfile August 2026 - Gia Matikainen</title>
                    <link>https://umbraco.com/blog/uprofile-august-2026-gia-matikainen/</link>
                    <description><![CDATA[Meet Gia: Lead Umbraco Developer dreaming of building a thriving Umbraco community in Finland]]></description>
                    <pubDate>Mon, 10 Aug 2026 00:00:00 Z</pubDate>
                        <category>hq</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/our.umbraco.hideit</guid>
                    <title>Our.Umbraco.HideIt</title>
                    <link>https://marketplace.umbraco.com/package/our.umbraco.hideit</link>
                    <description><![CDATA[The &quot;now you see me, now you don&#x27;t&quot; package for Umbraco blocks! Toggle block visibility with a single click. Hidden blocks are automatically filtered from frontend rendering.]]></description>
                    <pubDate>Mon, 10 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/thebuilder.blurplaceholder</guid>
                    <title>TheBuilder.BlurPlaceholder</title>
                    <link>https://marketplace.umbraco.com/package/thebuilder.blurplaceholder</link>
                    <description><![CDATA[Generate WebP, BlurHash, or ThumbHash placeholders for Umbraco Image media and deliver them as one frontend-ready string.]]></description>
                    <pubDate>Mon, 10 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://adamc95.medium.com/hardening-against-csv-injection-in-umbraco-c0e5ad44327e?source=rss------umbraco-5</guid>
                    <title>Hardening against CSV Injection in Umbraco</title>
                    <link>https://adamc95.medium.com/hardening-against-csv-injection-in-umbraco-c0e5ad44327e?source=rss------umbraco-5</link>
                    <description><![CDATA[&lt;div class=&quot;medium-feed-item&quot;&gt;&lt;p class=&quot;medium-feed-image&quot;&gt;&lt;a href=&quot;https://adamc95.medium.com/hardening-against-csv-injection-in-umbraco-c0e5ad44327e?source=rss------umbraco-5&quot;&gt;&lt;img src=&quot;https://cdn-images-1.medium.com/max/600/0*pJ3atjCwTUiDeUay.gif&quot; width=&quot;600&quot;&gt;&lt;/a&gt;&lt;/p&gt;&lt;p class=&quot;medium-feed-snippet&quot;&gt;Hello, long time no blog. It has certainly been a while but I am still doing penetration testing.&lt;/p&gt;&lt;p class=&quot;medium-feed-link&quot;&gt;&lt;a href=&quot;https://adamc95.medium.com/hardening-against-csv-injection-in-umbraco-c0e5ad44327e?source=rss------umbraco-5&quot;&gt;Continue reading on Medium &#xBB;&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;]]></description>
                    <pubDate>Sun, 09 Aug 2026 16:11:52 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umb.cachemanager</guid>
                    <title>Umb.CacheManager</title>
                    <link>https://marketplace.umbraco.com/package/umb.cachemanager</link>
                    <description><![CDATA[A backoffice dashboard for Umbraco 17 and later that allows you to view, inspect, and clear application caches without restarting the website.]]></description>
                    <pubDate>Sat, 08 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://dev.to/bernadet/expanding-the-backoffice-search-in-umbraco-highlighting-lesser-used-umbraco-features-2l4f</guid>
                    <title>Expanding the backoffice search in Umbraco - Highlighting lesser known Umbraco features</title>
                    <link>https://dev.to/bernadet/expanding-the-backoffice-search-in-umbraco-highlighting-lesser-used-umbraco-features-2l4f</link>
                    <description><![CDATA[&lt;p&gt;Recently, I started using &lt;a href=&quot;https://www.linkedin.com/in/erik-jan-westendorp/&quot; rel=&quot;noopener noreferrer&quot;&gt;Erik-Jan Westerndorp&#x27;s&lt;/a&gt; community package &quot;&lt;a href=&quot;https://marketplace.umbraco.com/package/umbraco.community.propertyeditors.heading&quot; rel=&quot;noopener noreferrer&quot;&gt;Heading&lt;/a&gt;&quot;. on a project. It&#x2019;s one of those packages that solves a very specific problem really neatly.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;In this case, the client wanted editors to be able to choose the heading level for a title on an element. So, for example, one image block might need an H2, while another might need an H3, depending on where it sits on the page.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The package worked great for that.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;But, as often happens, solving one problem uncovered another.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Not long after, the client came back with a new bit of feedback:&lt;/p&gt;&#xA;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;I can&#x2019;t search for the custom title I&#x2019;ve added.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&#xA;&lt;p&gt;And honestly, my first reaction was: &lt;em&gt;surely that should just work?&lt;/em&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;So I gave it a try - and they were right. The backoffice document search was only finding results based on the page name, not on values stored in custom fields.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&quot;https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8xkda7ei9wr9xbe0trjn.jpg&quot; class=&quot;article-body-image-wrapper&quot;&gt;&lt;img src=&quot;https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8xkda7ei9wr9xbe0trjn.jpg&quot; alt=&quot;Search for page name, finds result&quot; width=&quot;800&quot; height=&quot;383&quot;&gt;&lt;/a&gt;&lt;em&gt;Searching by page name returns the page&lt;/em&gt;&lt;br&gt;&#xA;&lt;a href=&quot;https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fowphbvusfxvmih85fm5p.jpg&quot; class=&quot;article-body-image-wrapper&quot;&gt;&lt;img src=&quot;https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fowphbvusfxvmih85fm5p.jpg&quot; alt=&quot;Search for page title, no result&quot; width=&quot;799&quot; height=&quot;344&quot;&gt;&lt;/a&gt;&lt;em&gt;Searching by page title returns no results&lt;/em&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The first thing I did was check the internal index &#x2014; and the title field &lt;em&gt;was&lt;/em&gt; there, so that allowed me to cross off one possible issue.&lt;br&gt;&#xA;&lt;a href=&quot;https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy40nrhth5q0pp5aghszs.jpg&quot; class=&quot;article-body-image-wrapper&quot;&gt;&lt;img src=&quot;https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy40nrhth5q0pp5aghszs.jpg&quot; alt=&quot;Internal index&quot; width=&quot;800&quot; height=&quot;393&quot;&gt;&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;So the content &lt;em&gt;was&lt;/em&gt; being indexed - it just wasn&#x2019;t being searched by the backoffice search.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I asked a few colleagues about it, and the general feeling was that this probably wasn&#x2019;t something you could change. The assumption was that Umbraco backoffice search just searches a predefined set of fields and that was that.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Still, it felt like there &lt;em&gt;had&lt;/em&gt; to be a way.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;And there is.&lt;/p&gt;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  The Missing Piece: UmbracoTreeSearcherFields&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;It turns out this is already supported and documented, but it was a feature I hadn&#x2019;t come across before. Since I suspect I&#x2019;m not the only one, it&#x2019;s worth highlighting here:&lt;/p&gt;&#xA;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;a href=&quot;https://docs.umbraco.com/umbraco-cms/extend-your-project/server-side-extensions/backoffice-search&quot; rel=&quot;noopener noreferrer&quot;&gt;Backoffice Search - A guide to customization of Backoffice Search&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&#xA;&lt;p&gt;That article introduced me to &lt;strong&gt;UmbracoTreeSearcherFields&lt;/strong&gt;, which controls the indexed fields used by backoffice search. By replacing it with a custom implementation, you can expand the list of searchable fields.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;My first attempt looked like this:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight csharp&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CustomUmbracoTreeSearcherFields&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ILanguageService&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;languageService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;UmbracoTreeSearcherFields&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;languageService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IUmbracoTreeSearcherFields&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IEnumerable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetBackOfficeDocumentFields&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;base&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetBackOfficeFields&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;title&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;I restarted my environment, tried again&#x2026; and it still didn&#x2019;t work.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Backoffice search could still only find the page by name.&lt;/p&gt;&#xA;&#xA;&lt;h3&gt;&#xA;  &#xA;  &#xA;  The Catch: Variant Field Names&#xA;&lt;/h3&gt;&#xA;&#xA;&lt;p&gt;After taking a closer look at the index, the reason became clear: the field key wasn&#x2019;t simply title. Because the property had language variants, the indexed field name includes the language ISO code.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;So instead of hardcoding a single field name, I updated the implementation to generate the variant field names dynamically. That also makes it more future-proof &#x2014; if new languages are added later, search continues to work without any code changes.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Here&#x2019;s the updated version:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight csharp&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CustomUmbracoTreeSearcherFields&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ILanguageService&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;languageService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;UmbracoTreeSearcherFields&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;languageService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IUmbracoTreeSearcherFields&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TitleAlias&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PublishedModelHelper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetModelPropertyAlias&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Page&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&#xA;&#xA;    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IEnumerable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetBackOfficeDocumentFields&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;base&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetBackOfficeDocumentFields&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Concat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetVariantFieldNames&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TitleAlias&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&#xA;    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IEnumerable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetVariantFieldNames&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;alias&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&#xA;        &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;languageService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetAllAsync&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetAwaiter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetResult&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Select&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;l&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;$&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;alias&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;l&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IsoCode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToLowerInvariant&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;And with that in place, the backoffice search started returning results based on the custom title value as well.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&quot;https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe1tz7ifjj35o7ohvoeyb.jpg&quot; class=&quot;article-body-image-wrapper&quot;&gt;&lt;img src=&quot;https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe1tz7ifjj35o7ohvoeyb.jpg&quot; alt=&quot;Search for page title, finds result&quot; width=&quot;798&quot; height=&quot;344&quot;&gt;&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  Why I&#x2019;m sharing this&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;This is one of those things that&#x2019;s probably obvious once you&#x2019;ve worked with it before, but until then, it&#x2019;s easy to assume backoffice search is less flexible than it actually is.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;If you&#x2019;ve got editors relying on custom fields it&#x2019;s worth checking whether those fields are included in backoffice search. If they&#x2019;re already indexed, you may only need to extend UmbracoTreeSearcherFields to make them searchable.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;A small change, but a very useful one for editors.&lt;/p&gt;]]></description>
                    <pubDate>Fri, 07 Aug 2026 12:53:14 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://manifesto.co.uk/thinking/technology/umbraco-codegarden-day-1-ai-elements-awards</guid>
                    <title>Umbraco Codegarden 2026 Day 1: AI, Elements &amp; Community News | manifesto</title>
                    <link>https://manifesto.co.uk/thinking/technology/umbraco-codegarden-day-1-ai-elements-awards</link>
                    <description><![CDATA[Explore key takeaways from Day 1 of Umbraco Codegarden 2026, including major product keynotes, AI governance, new Elements features, and the Umbraco Awards.]]></description>
                    <pubDate>Fri, 07 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.commandpalette</guid>
                    <title>Umbraco.Community.CommandPalette</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.commandpalette</link>
                    <description><![CDATA[A Cmd&#x2B;K command palette for the Umbraco backoffice. Jump to any node, run an action on the current node, or switch section - without touching the mouse or waiting for the content tree to expand.]]></description>
                    <pubDate>Fri, 07 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.simplestats</guid>
                    <title>Umbraco.Community.SimpleStats</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.simplestats</link>
                    <description><![CDATA[A lightweight Umbraco backoffice package that tracks page views for your content and shows the results inside the CMS &#x2014; no external analytics service, tracking snippet, or cookies required.]]></description>
                    <pubDate>Fri, 07 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://www.nevitech.co.uk/blog/setting-up-windows-server-2025-for-umbraco/</guid>
                    <title>Setting up Windows Server 2025 for Umbraco</title>
                    <link>https://www.nevitech.co.uk/blog/setting-up-windows-server-2025-for-umbraco/</link>
                    <description><![CDATA[Every time I build a new server I go through the same sequence, and every time I find myself trying to remember what I did last time. So this is my reference for turning a clean Windows Server 2025 instance into something that will happily host Umbraco on IIS and SQL Express, in the order I actually do things.]]></description>
                    <pubDate>Thu, 06 Aug 2026 23:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://umbracocommunity.social/@umbraco/117047410343596739</guid>
                    <title>Umbraco CMS 17.6 and 18.1 are out </title>
                    <link>https://umbracocommunity.social/@umbraco/117047410343596739</link>
                    <description><![CDATA[Umbraco CMS 17.6 and 18.1 are out &#x1F389;Upgrade to get small features, performance improvements, and another round of bug fixes. Find the release notes here:#Umbraco 17.6: https://umbra.co/4pU0kBbhttps://umbra.co/4fGA9u4  #Umbraco 18.1: https://umbra.co/4fwezY4https://umbra.co/4pV0c4a#Umbraco]]></description>
                    <pubDate>Thu, 06 Aug 2026 19:14:00 Z</pubDate>
                        <category>mastodon</category>
                        <category>social</category>
                        <category>hq</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/reflections.umbraco17.starterkit</guid>
                    <title>Reflections.Umbraco17.StarterKit</title>
                    <link>https://marketplace.umbraco.com/package/reflections.umbraco17.starterkit</link>
                    <description><![CDATA[Reflections.Umbraco17.StarterKit]]></description>
                    <pubDate>Thu, 06 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/reflections.umbraco18.starterkit</guid>
                    <title>Reflections.Umbraco18.StarterKit</title>
                    <link>https://marketplace.umbraco.com/package/reflections.umbraco18.starterkit</link>
                    <description><![CDATA[A ready-to-use starter website, schema, templates, media, SEO fields, and sample content for Umbraco 18.]]></description>
                    <pubDate>Thu, 06 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://umbracocommunity.social/@owaincodes/117042396570290086</guid>
                    <title>Automation for the People - Coming to an Umbraco meetup soon</title>
                    <link>https://umbracocommunity.social/@owaincodes/117042396570290086</link>
                    <description><![CDATA[Coming to an Umbraco meetup soon. Shame these aren&#x27;t in-person but will still be great to see all the umbracians from around the world. #umbraco]]></description>
                    <pubDate>Wed, 05 Aug 2026 16:55:00 Z</pubDate>
                        <category>community</category>
                        <category>social</category>
                        <category>mastodon</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/sa.automate.clockify</guid>
                    <title>SA.Automate.Clockify</title>
                    <link>https://marketplace.umbraco.com/package/sa.automate.clockify</link>
                    <description><![CDATA[Clockify connection types and actions for Umbraco Automate. Start and stop timers, or log a completed entry by duration or explicit dates, as part of an automation workflow.]]></description>
                    <pubDate>Wed, 05 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/sa.automate.brickset</guid>
                    <title>SA.Automate.Brickset</title>
                    <link>https://marketplace.umbraco.com/package/sa.automate.brickset</link>
                    <description><![CDATA[Brickset connection types and actions for Umbraco Automate. Look up and search LEGO sets as part of an automation workflow.]]></description>
                    <pubDate>Wed, 05 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/our.umbraco.loginbranding</guid>
                    <title>Our.Umbraco.LoginBranding</title>
                    <link>https://marketplace.umbraco.com/package/our.umbraco.loginbranding</link>
                    <description><![CDATA[White-label the Umbraco backoffice login screen from Content &#x2192; Login Branding. Editors pick background and logo images from Media, set a custom greeting and supporting text, and preview desktop/mobile before saving.]]></description>
                    <pubDate>Wed, 05 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://bsky.app/profile/aaronsadler.dev/post/3msb2mlwmps2i</guid>
                    <title>Interim fix for memory issues when running Umbraco on Docker </title>
                    <link>https://bsky.app/profile/aaronsadler.dev/post/3msb2mlwmps2i</link>
                    <description><![CDATA[I&#x27;ve released a package as an interim fix for memory issues when running Umbraco on Docker with memory limits, it targets V13, V17 and V18.&#xA;&#xA;You can read the issue here:&#xA;https://github.com/umbraco/Umbraco-CMS/issues/23556&#xA;&#xA;You can grab the package here:&#xA;https://www.nuget.org/packages/Umbraco.Community.Imaging.ImageSharp/1.1.0&#xA;&#xA;#Umbraco #NuGet]]></description>
                    <pubDate>Tue, 04 Aug 2026 13:54:00 Z</pubDate>
                        <category>community</category>
                        <category>bluesky</category>
                        <category>social</category>
                </item>
                <item>
                    <guid>https://skrift.io/issues/#130</guid>
                    <title>Skrift Issue #130</title>
                    <link>https://skrift.io/issues/#130</link>
                    <description><![CDATA[Featuring guest posts by Jesper Mayntzhusen on &quot;Preparing your site and packages for load balancing&quot; and Nathaniel Grantham-Knight on &quot;How to build an Umbraco 17 dashboard with Vite&quot;]]></description>
                    <pubDate>Tue, 04 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                        <category>skrift</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.imaging.imagesharp</guid>
                    <title>Umbraco.Community.Imaging.ImageSharp</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.imaging.imagesharp</link>
                    <description><![CDATA[Stops Umbraco sites being OOM-killed in memory-limited containers while browsing the media section. ImageSharp decodes each source image at full resolution before resizing, and concurrent thumbnail requests are not bounded, so peak memory is the number of images being processed at once multiplied by the decoded source size. This package caps both the unmanaged buffer pool ImageSharp retains between requests and how many images are processed concurrently, deriving both from the memory available to the process. It is a backport of the fix proposed for the CMS in umbraco/Umbraco-CMS#23557, for Umbraco 17 sites that need it before it ships in the product.]]></description>
                    <pubDate>Tue, 04 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.imaging.imagesharp2</guid>
                    <title>Umbraco.Community.Imaging.ImageSharp2</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.imaging.imagesharp2</link>
                    <description><![CDATA[Stops Umbraco sites being OOM-killed in memory-limited containers while browsing the media section. ImageSharp decodes each source image at full resolution before resizing, and concurrent thumbnail requests are not bounded, so peak memory is the number of images being processed at once multiplied by the decoded source size. This package caps both the unmanaged buffer pool ImageSharp retains between requests and how many images are processed concurrently, deriving both from the memory available to the process. It is a backport of the fix proposed for the CMS in umbraco/Umbraco-CMS#23557, for Umbraco 17 sites that need it before it ships in the product.]]></description>
                    <pubDate>Tue, 04 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.ai.templatewizard</guid>
                    <title>Umbraco.Community.AI.TemplateWizard</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.ai.templatewizard</link>
                    <description><![CDATA[AI.Template Wizard is an Umbraco CMS package that exposes AI tools for working with templates, partial views, and block components. It integrates with the Umbraco.AI framework.]]></description>
                    <pubDate>Tue, 04 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/wayfinder.umbraco</guid>
                    <title>Wayfinder.Umbraco</title>
                    <link>https://marketplace.umbraco.com/package/wayfinder.umbraco</link>
                    <description><![CDATA[Umbraco-hosted implementation of Wayfinder service design &#x2014; a DB-backed, uSync-portable service blueprint store, backoffice authoring API, and GDS-style stage rendering (controllers, tag helpers, Razor views) for any Umbraco v17&#x2B; site. No multi-tenancy or auth opinions of its own; a host wires its own identity/tenant resolution on top.]]></description>
                    <pubDate>Mon, 03 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/uskinnedsitebuilder.starterkit.wellspring</guid>
                    <title>uSkinnedSiteBuilder.StarterKit.Wellspring</title>
                    <link>https://marketplace.umbraco.com/package/uskinnedsitebuilder.starterkit.wellspring</link>
                    <description><![CDATA[Wellspring Starter Kit for uSkinned Site Builder for Umbraco CMS]]></description>
                    <pubDate>Mon, 03 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/uskinnedsitebuilder.starterkit.hairco</guid>
                    <title>uSkinnedSiteBuilder.StarterKit.HairCo</title>
                    <link>https://marketplace.umbraco.com/package/uskinnedsitebuilder.starterkit.hairco</link>
                    <description><![CDATA[HairCo Starter Kit for uSkinned Site Builder for Umbraco CMS]]></description>
                    <pubDate>Mon, 03 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.skynetaccessibilityscanner</guid>
                    <title>Umbraco.Community.SkynetAccessibilityScanner</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.skynetaccessibilityscanner</link>
                    <description><![CDATA[Scan, monitor, and identify website accessibility issues across WCAG 2.0, 2.1, 2.2, ADA, Section 508, EN 301 549, UK Equality Act, Australian DDA, and Canada ACA, directly from the Umbraco backoffice.]]></description>
                    <pubDate>Sun, 02 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/knowit.umbraco.instantblockpreview.v17</guid>
                    <title>Knowit.Umbraco.InstantBlockPreview.V17</title>
                    <link>https://marketplace.umbraco.com/package/knowit.umbraco.instantblockpreview.v17</link>
                    <description><![CDATA[Instant block and grid previews in Umbraco without saving your documents]]></description>
                    <pubDate>Sat, 01 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.kanban</guid>
                    <title>Umbraco.Community.Kanban</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.kanban</link>
                    <description><![CDATA[Kanban board and calendar views for Umbraco child nodes.]]></description>
                    <pubDate>Sat, 01 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.kanban.contentment</guid>
                    <title>Umbraco.Community.Kanban.Contentment</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.kanban.contentment</link>
                    <description><![CDATA[Contentment Property provider for Umbraco.Community.Kanban]]></description>
                    <pubDate>Sat, 01 Aug 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://community.umbraco.com/blog/2026/07/an-hour-on-our-one-last-time/</guid>
                    <title>An Hour on Our One Last Time</title>
                    <link>https://community.umbraco.com/blog/2026/07/an-hour-on-our-one-last-time/</link>
                    <description><![CDATA[The end of an era: after 15&#x2B; years, I&#x27;ve switched off our.umbraco.com. I wrote up some of the story, the karma, the spam wars and a few fond arguments https://community.umbraco.com/blog/2026/07/an-hour-on-our-one-last-time/#Umbraco #H5YR Our.]]></description>
                    <pubDate>Fri, 31 Jul 2026 10:20:00 Z</pubDate>
                        <category>blog</category>
                        <category>community</category>
                </item>
                <item>
                    <guid>https://www.youtube.com/watch?v=RaFus8cVC24</guid>
                    <title>umbraCoffee - Summer Vibes Only</title>
                    <link>https://www.youtube.com/watch?v=RaFus8cVC24</link>
                    <description><![CDATA[Welcome to your monthly dose of #umbraCoffee&#x200B;&#x200B;&#x200B;&#x200B;&#x200B;&#x200B;&#x200B;&#x200B;&#x200B;&#x200B;&#x200B;&#x200B;! Your hosts - Marcin and Callum - together with their guest(s) will drive through all of the community news and happenings in the Umbraco world. So... grab a cuppa, join us LIVE and enjoy!&#xA;&#xA;See ya?!&#xA;&#xA;---&#xA;&#x2615; Wanna buy us a coffee/pizza/donuts?&#xA;https://www.buymeacoffee.com/umbracoffee&#xA;---&#xA;&#xA;Notes:&#xA;&#xA;// TODO]]></description>
                    <pubDate>Fri, 31 Jul 2026 10:14:35 Z</pubDate>
                        <category>community</category>
                        <category>youtube</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.schemeweaver.deploy</guid>
                    <title>Umbraco.Community.SchemeWeaver.Deploy</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.schemeweaver.deploy</link>
                    <description><![CDATA[Umbraco Deploy addon for SchemeWeaver &#x2014; deploys Schema.org mappings between environments as disk-based Deploy artifacts, alongside the document types they belong to. Requires Umbraco Deploy (OnPrem or Cloud) on the host site.]]></description>
                    <pubDate>Fri, 31 Jul 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://umbraco.com/blog/designing-umbraco-with-umbraco-building-a-backoffice-design-system-in-claude-design/</guid>
                    <title>Designing Umbraco with Umbraco: building a backoffice design system in Claude Design</title>
                    <link>https://umbraco.com/blog/designing-umbraco-with-umbraco-building-a-backoffice-design-system-in-claude-design/</link>
                    <description><![CDATA[Create high-fidelity, interactive prototypes and mock-ups in no time. Discover how to build an Umbraco backoffice design system using Claude Design.]]></description>
                    <pubDate>Thu, 30 Jul 2026 00:00:00 Z</pubDate>
                        <category>hq</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://examinex.online/2026/07/29/version-10-0-0-released</guid>
                    <title>ExamineX 10.0 for Azure Search and 7.0 for Elasticsearch released to support Umbraco 18</title>
                    <link>https://examinex.online/2026/07/29/version-10-0-0-released</link>
                    <description><![CDATA[ExamineX 10.0 for Azure Search and 7.0 for Elasticsearch released to support Umbraco 18]]></description>
                    <pubDate>Wed, 29 Jul 2026 19:52:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://www.wearediagram.com/blog/why-umbraco-17-is-more-than-an-end-of-life-escape</guid>
                    <title>Why Umbraco 17 Is More Than an End-of-Life Escape</title>
                    <link>https://www.wearediagram.com/blog/why-umbraco-17-is-more-than-an-end-of-life-escape</link>
                    <description><![CDATA[&amp;nbsp;]]></description>
                    <pubDate>Wed, 29 Jul 2026 15:40:39 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.automate.clickup</guid>
                    <title>Umbraco.Community.Automate.ClickUp</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.automate.clickup</link>
                    <description><![CDATA[OAuth-based ClickUp provider for Umbraco Automate.]]></description>
                    <pubDate>Wed, 29 Jul 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/utpro.feature.seoaudit</guid>
                    <title>uTPro.Feature.SEOAudit</title>
                    <link>https://marketplace.umbraco.com/package/utpro.feature.seoaudit</link>
                    <description><![CDATA[Site-wide SEO &amp; content audit for Umbraco (16, 17, 18). Crawls every Content &amp; Media URL (plus sitemap.xml), checks for broken links, images and resources, and audits each page: SEO (title, meta description, canonical, H1-H3, noindex/nofollow, lang), Open Graph &amp; Twitter cards, technical SEO (HTTPS, gzip, browser caching, schema.org, viewport, favicon), content quality (word count, readability, keyword density, thin &amp; duplicate content), a static accessibility subset and estimated carbon emissions with an A-F rating. Get a per-run health score, a per-page composite SEO score (Lighthouse-style, 0-100), issues grouped by severity and priority, orphaned-page detection, incremental scans, CSV export and a per-page detail view - all inside the backoffice. Adds a per-node SEO Audit tab in the Content and Media editors that auto-audits on open. Runs as a recurring background job (auto-discovered by uTPro Job Monitor). Server-side and SSRF-safe. Built on the framework-agnostic T4VN.Seo.Core engine.]]></description>
                    <pubDate>Wed, 29 Jul 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/geochecker.umbraco</guid>
                    <title>GeoChecker.Umbraco</title>
                    <link>https://marketplace.umbraco.com/package/geochecker.umbraco</link>
                    <description><![CDATA[Scores how ready your Umbraco site is to be found and cited by AI engines &#x2014; llms.txt, robots.txt AI rules, sitemap, structured data and more &#x2014; from a dashboard in the backoffice.]]></description>
                    <pubDate>Wed, 29 Jul 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/sa.automate.qrcode</guid>
                    <title>SA.Automate.QRcode</title>
                    <link>https://marketplace.umbraco.com/package/sa.automate.qrcode</link>
                    <description><![CDATA[QR code generation actions for Umbraco Automate, powered by QRCoder. Generate a QR code for a URL as part of an automation workflow.]]></description>
                    <pubDate>Wed, 29 Jul 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://www.linkedin.com/posts/umbraco-dutchumbracoalliance-developercommunity-share-7487806765947076608-9G4d/?utm_source=share&amp;utm_medium=member_desktop&amp;rcm=ACoAAAa7vhsBsn9_Sr12Vc0j55T5l3l83ogK05g</guid>
                    <title>First speaker announced for Dutch Umbraco Alliance Festival </title>
                    <link>https://www.linkedin.com/posts/umbraco-dutchumbracoalliance-developercommunity-share-7487806765947076608-9G4d/?utm_source=share&amp;utm_medium=member_desktop&amp;rcm=ACoAAAa7vhsBsn9_Sr12Vc0j55T5l3l83ogK05g</link>
                    <description><![CDATA[First speaker announced for Dutch Umbraco Alliance Festival ]]></description>
                    <pubDate>Tue, 28 Jul 2026 12:19:00 Z</pubDate>
                        <category>community</category>
                        <category>social</category>
                        <category>linkedin</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/mgc.instagramfeed</guid>
                    <title>MGC.InstagramFeed</title>
                    <link>https://marketplace.umbraco.com/package/mgc.instagramfeed</link>
                    <description><![CDATA[A high-performance Razor Class Library for Umbraco 17 (.NET 10) that integrates Instagram feeds using the official Instagram Graph API (v21.0). &#xA;      Features automatic Umbraco dictionary item seeding through package migration, secure configuration of Instagram Access Token and User ID via &#xA;      Umbraco Dictionary keys, zero-config dependency injection registration through InstagramComposer, and strongly typed C# models for Instagram &#xA;      profile data and media items including images, reels, and carousel albums with captions, like counts, comment counts, thumbnails, media URLs, &#xA;      and permalinks.]]></description>
                    <pubDate>Tue, 28 Jul 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.netlifydashboard</guid>
                    <title>Umbraco.Community.NetlifyDashboard</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.netlifydashboard</link>
                    <description><![CDATA[A backoffice dashboard for Netlify: connect with a personal access token, view your last deploys and their status, and purge the Netlify CDN cache (full or by cache tag).]]></description>
                    <pubDate>Tue, 28 Jul 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://umbraco.com/blog/security-advisory-july-28-2026-security-patches-for-umbraco-forms-are-now-available/</guid>
                    <title>Security Patches for Umbraco Forms are now available</title>
                    <link>https://umbraco.com/blog/security-advisory-july-28-2026-security-patches-for-umbraco-forms-are-now-available/</link>
                    <description><![CDATA[A high-level security vulnerability has been identified in Umbraco Forms. A security patch for Umbraco Forms 13, 17, and 18 is out now. We highly recommend upgrading.]]></description>
                    <pubDate>Tue, 28 Jul 2026 00:00:00 Z</pubDate>
                        <category>hq</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://owain.codes/blog/2026/july/a-reusable-deploy-pipeline-for-umbraco-cloud/</guid>
                    <title>A reusable deploy pipeline for Umbraco Cloud</title>
                    <link>https://owain.codes/blog/2026/july/a-reusable-deploy-pipeline-for-umbraco-cloud/</link>
                    <description><![CDATA[Create a reusable deploy pipeline for Umbraco Cloud]]></description>
                    <pubDate>Mon, 27 Jul 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbhost.automate.teamwork</guid>
                    <title>UmbHost.Automate.Teamwork</title>
                    <link>https://marketplace.umbraco.com/package/umbhost.automate.teamwork</link>
                    <description><![CDATA[Teamwork Projects connection type and actions for Umbraco Automate.]]></description>
                    <pubDate>Fri, 24 Jul 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbhost.automate.github</guid>
                    <title>UmbHost.Automate.GitHub</title>
                    <link>https://marketplace.umbraco.com/package/umbhost.automate.github</link>
                    <description><![CDATA[GitHub connection type, actions, a jsonpath binding filter and an X-Hub-Signature-256 webhook authenticator for Umbraco Automate.]]></description>
                    <pubDate>Fri, 24 Jul 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://umbraco.com/blog/security-advisory-upcoming-security-patch-for-umbraco-forms-ready-on-july-28-2026-at-08-am-utc/</guid>
                    <title>Security Advisory: Upcoming Security Patch for Umbraco Forms ready on July 28, 2026 at 08 AM UTC</title>
                    <link>https://umbraco.com/blog/security-advisory-upcoming-security-patch-for-umbraco-forms-ready-on-july-28-2026-at-08-am-utc/</link>
                    <description><![CDATA[A security vulnerability has been identified in Umbraco Forms. A security patch for Umbraco Forms 13, 17, and 18 are scheduled for release on Tuesday, July 28th, 2026 at 08 AM UTC.]]></description>
                    <pubDate>Thu, 23 Jul 2026 00:00:00 Z</pubDate>
                        <category>hq</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://www.youtube.com/watch?v=QB05kK-yAt4</guid>
                    <title>uSkinned Upgrade Umbraco Cloud 13 to 17</title>
                    <link>https://www.youtube.com/watch?v=QB05kK-yAt4</link>
                    <description><![CDATA[Upgrade Umbraco Cloud 13 to 17 | uSkinned Site Builder 6 to 7 | Tutorial - YouTube]]></description>
                    <pubDate>Wed, 22 Jul 2026 12:56:00 Z</pubDate>
                        <category>community</category>
                        <category>youtube</category>
                </item>
                <item>
                    <guid>https://www.youtube.com/watch?v=D-ypwpXtZYA</guid>
                    <title>uSkinned Upgrade Umbraco CMS 8 to 17</title>
                    <link>https://www.youtube.com/watch?v=D-ypwpXtZYA</link>
                    <description><![CDATA[Upgrade Umbraco CMS 8 to 17 | uSkinned Site Builder 1 to 7 | Tutorial - YouTube]]></description>
                    <pubDate>Wed, 22 Jul 2026 12:56:00 Z</pubDate>
                        <category>community</category>
                        <category>youtube</category>
                </item>
                <item>
                    <guid>https://uskinned.net/blog/two-upgrade-guides-to-help-you-get-to-umbraco-17/</guid>
                    <title>uSkinned Umbraco 17 Upgrade Video Guides</title>
                    <link>https://uskinned.net/blog/two-upgrade-guides-to-help-you-get-to-umbraco-17/</link>
                    <description><![CDATA[Umbraco 17 Upgrade Video Guides&#xA;&#xA;Ready to make the move to Umbraco 17? We&#x27;ve got you covered. &#xA;&#xA;We&#x27;ve created two practical video guides to help you upgrade to the latest Long-Term Support (LTS) release. Whether you&#x27;re running a long-standing self-hosted project or an Umbraco Cloud website, Marc walks you through the process step by step.]]></description>
                    <pubDate>Wed, 22 Jul 2026 12:55:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://umbraco.com/blog/green-track-to-codegarden/</guid>
                    <title>The Green Track to Codegarden</title>
                    <link>https://umbraco.com/blog/green-track-to-codegarden/</link>
                    <description><![CDATA[Discover how Umbraco&#x27;s Green Track travelers saved 1.5 tonnes of CO2 by taking the train to Codegarden, redefining productive and sustainable business travel.]]></description>
                    <pubDate>Wed, 22 Jul 2026 00:00:00 Z</pubDate>
                        <category>hq</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.ai.mediajanitor</guid>
                    <title>Umbraco.Community.AI.MediaJanitor</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.ai.mediajanitor</link>
                    <description><![CDATA[An AI Media Assistant for the Umbraco Media section. Finds images with missing alt text, generic names, or in the wrong folder and suggests a better file name, alt text, caption, and folder &#x2014; you review, edit, and apply.]]></description>
                    <pubDate>Tue, 21 Jul 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.linkedpages</guid>
                    <title>Umbraco.Community.LinkedPages</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.linkedpages</link>
                    <description><![CDATA[Package Description]]></description>
                    <pubDate>Tue, 21 Jul 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.headsup</guid>
                    <title>Umbraco.Community.HeadsUp</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.headsup</link>
                    <description><![CDATA[Protects Umbraco editors against lost content when the same document is open in multiple tabs or edited by multiple users. Notifies other editors in real time when a document they have open is saved or published, lists the changed fields and offers to reload.]]></description>
                    <pubDate>Tue, 21 Jul 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.adminonly</guid>
                    <title>Umbraco.Community.AdminOnly</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.adminonly</link>
                    <description><![CDATA[A friendlier backoffice for non-admin editors. Hide document types, tabs and properties from everyone who isn&#x27;t an administrator &#x2014; without touching user groups, permissions or document type structure. Editors see only what&#x27;s relevant to their work; admins keep the full picture, with a lock icon marking every hidden item. Configuration is point-and-click from a settings dashboard, so there is no code to write and nothing to recompile. Note: this is a backoffice UX layer, not server-side authorization &#x2014; use Umbraco&#x27;s user groups and permissions to protect sensitive data.]]></description>
                    <pubDate>Tue, 21 Jul 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.iconpicker</guid>
                    <title>Umbraco.Community.IconPicker</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.iconpicker</link>
                    <description><![CDATA[Pick SVG icons straight from your own sprite. IconPicker adds a property editor that reads any SVG sprite in your site&#x27;s wwwroot folder and lets editors choose a symbol from it &#x2014; no icon library to install, no duplicate assets. The icons your designer delivered are the icons your editors get.]]></description>
                    <pubDate>Tue, 21 Jul 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://flowcourier.com/blog/aeo-for-umbraco/</guid>
                    <title>AEO for Umbraco: Your Next Visitor Is an AI</title>
                    <link>https://flowcourier.com/blog/aeo-for-umbraco/</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Mon, 20 Jul 2026 17:24:00 Z</pubDate>
                        <category>blog</category>
                        <category>community</category>
                </item>
                <item>
                    <guid>https://blog.tsd.digital/assume-your-software-will-outlive-its-end-of-life/</guid>
                    <title>Assume your software will outlive its end-of-life</title>
                    <link>https://blog.tsd.digital/assume-your-software-will-outlive-its-end-of-life/</link>
                    <description><![CDATA[We still run an Umbraco v4 site, on purpose. End-of-life is a date on the vendor&#x27;s calendar, not a fact about your customer&#x27;s business. Why the version you ship is the one worth designing for, and how to tell a managed risk from plain neglect.]]></description>
                    <pubDate>Mon, 20 Jul 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/thebuilder.webanalytics</guid>
                    <title>TheBuilder.WebAnalytics</title>
                    <link>https://marketplace.umbraco.com/package/thebuilder.webanalytics</link>
                    <description><![CDATA[Vercel Web Analytics inside the Umbraco backoffice.]]></description>
                    <pubDate>Sun, 19 Jul 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.formsaudittrail</guid>
                    <title>Umbraco.Community.FormsAuditTrail</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.formsaudittrail</link>
                    <description><![CDATA[A view-only audit trail for Umbraco Forms design changes. Tracks who changed what on form designs (fields, pages, workflows and form settings) and surfaces the history in a backoffice dashboard with filtering, field-level diffs and CSV export.]]></description>
                    <pubDate>Fri, 17 Jul 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/utpro.feature.urlviewer</guid>
                    <title>uTPro.Feature.UrlViewer</title>
                    <link>https://marketplace.umbraco.com/package/utpro.feature.urlviewer</link>
                    <description><![CDATA[Fetch and inspect any URL as Googlebot, Bingbot or a real browser, directly from your Umbraco site (Umbraco 16, 17, 18). Follows the full redirect chain and shows the response headers for every hop, renders the raw HTML source with line numbers, and analyses the page for spam/hack keywords, hidden CSS (a common cloaking trick), meta tags and common JavaScript issues (eval, document.write, obfuscation, mixed content and more). Includes automatic cloaking detection that compares what a search-engine bot sees versus what Chrome sees, plus a one-click VirusTotal link for the domain. Ideal for SEO debugging, diagnosing hacked or cloaked pages, and inspecting redirects. The fetch runs server-side and blocks private/local addresses for safety.]]></description>
                    <pubDate>Fri, 17 Jul 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/cloudlens</guid>
                    <title>CloudLens</title>
                    <link>https://marketplace.umbraco.com/package/cloudlens</link>
                    <description><![CDATA[Compare content between Umbraco Cloud environments from the backoffice before every deployment.]]></description>
                    <pubDate>Fri, 17 Jul 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://owain.codes/blog/2026/july/build-a-custom-umbraco-automate-action/</guid>
                    <title>Build a custom Umbraco Automate action</title>
                    <link>https://owain.codes/blog/2026/july/build-a-custom-umbraco-automate-action/</link>
                    <description><![CDATA[Creating a custom action in Umbraco Automate to pull tags from a blog and display them as hashtags in social connections.]]></description>
                    <pubDate>Fri, 17 Jul 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://umbracocommunity.social/@owaincodes/116928799744745888</guid>
                    <title>Owain.Codes v2 Umbraco Automate packages for Bluesky, Mastodon and LinkedIn have been released.</title>
                    <link>https://umbracocommunity.social/@owaincodes/116928799744745888</link>
                    <description><![CDATA[Busy night - version 2 of my Umbraco.Automate packages have been released. Changing the config pattern and a few improvements. Bluesky, Mastodon and LinkedIn packages all updated. #umbraco]]></description>
                    <pubDate>Thu, 16 Jul 2026 10:59:00 Z</pubDate>
                        <category>community</category>
                        <category>mastodon</category>
                        <category>social</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/flowcourier.umbraco.aeo</guid>
                    <title>Flowcourier.Umbraco.AEO</title>
                    <link>https://marketplace.umbraco.com/package/flowcourier.umbraco.aeo</link>
                    <description><![CDATA[Make your Umbraco site readable by AI answer engines (ChatGPT, Claude, Perplexity, Gemini, &#x2026;). Install one package and your site immediately serves an /llms.txt index, an /llms-full.txt full-site Markdown dump, and a clean Markdown rendering of any page when you append .md to its URL &#x2014; all generated live from the published-content cache, with no editor work and no content changes. Multi-site and multilingual aware, discoverable via alternate links, content negotiation and an optional robots.txt hint, with ETag/304 caching built in. Designed for sites where Umbraco renders the front end (Razor/MVC) &#x2014; not for headless setups. Free for Umbraco 17.5&#x2B;, including commercial production use.]]></description>
                    <pubDate>Thu, 16 Jul 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/esatto.umbraco.backoffice.dictionarylocalization</guid>
                    <title>Esatto.Umbraco.Backoffice.DictionaryLocalization</title>
                    <link>https://marketplace.umbraco.com/package/esatto.umbraco.backoffice.dictionarylocalization</link>
                    <description><![CDATA[Bridges Umbraco 17 content Dictionary items into the backoffice UI localization system. After install, any `#Key` in a content-type property label (or anywhere `localize.string()` is called) resolves to the current backoffice user&#x27;s culture value from the Dictionary section. Works for every existing and future dictionary key; no per-key manifest wiring.]]></description>
                    <pubDate>Thu, 16 Jul 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/foxcart.members</guid>
                    <title>FoxCart.Members</title>
                    <link>https://marketplace.umbraco.com/package/foxcart.members</link>
                    <description><![CDATA[Member area addon for FoxCart: profile management, order history, saved addresses and complete authentication flows built on Umbraco Members. Ships as a Razor Class Library with overridable Flowbite-style default views.]]></description>
                    <pubDate>Thu, 16 Jul 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://medium.com/@associative-india/top-umbraco-development-company-in-pune-associative-780722f22eb2?source=rss------umbraco-5</guid>
                    <title>Top Umbraco Development Company in Pune | Associative</title>
                    <link>https://medium.com/@associative-india/top-umbraco-development-company-in-pune-associative-780722f22eb2?source=rss------umbraco-5</link>
                    <description><![CDATA[&lt;div class=&quot;medium-feed-item&quot;&gt;&lt;p class=&quot;medium-feed-image&quot;&gt;&lt;a href=&quot;https://medium.com/@associative-india/top-umbraco-development-company-in-pune-associative-780722f22eb2?source=rss------umbraco-5&quot;&gt;&lt;img src=&quot;https://cdn-images-1.medium.com/max/1080/1*-vNHPgEKoCTInnwPbQpBcA.png&quot; width=&quot;1080&quot;&gt;&lt;/a&gt;&lt;/p&gt;&lt;p class=&quot;medium-feed-snippet&quot;&gt;Welcome to Associative, a premier full-service software development firm headquartered in Pune, Maharashtra, India.&lt;/p&gt;&lt;p class=&quot;medium-feed-link&quot;&gt;&lt;a href=&quot;https://medium.com/@associative-india/top-umbraco-development-company-in-pune-associative-780722f22eb2?source=rss------umbraco-5&quot;&gt;Continue reading on Medium &#xBB;&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;]]></description>
                    <pubDate>Wed, 15 Jul 2026 10:15:28 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.getnet</guid>
                    <title>SplatDev.Umbraco.Plugins.Getnet</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.getnet</link>
                    <description><![CDATA[Umbraco 17 plugin that registers the Getnet (Santander acquirer) SDK (SplatDev.Payments.Getnet): options binding, the API client, and the named Getnet HttpClient. Webhook/backoffice controllers and payment orchestration are application-specific and stay in the consuming app.]]></description>
                    <pubDate>Wed, 15 Jul 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.santander</guid>
                    <title>SplatDev.Umbraco.Plugins.Santander</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.santander</link>
                    <description><![CDATA[Umbraco 17 plugin for the Santander Open Banking suite: a composer that registers SplatDev.Payments.Santander (options, client, the 8 product services, and the named mTLS HttpClient with the ICP-Brasil e-CNPJ certificate) plus a guarded backoffice/server-to-server banking API controller.]]></description>
                    <pubDate>Wed, 15 Jul 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/dragonfly.umbraco10.forms.web</guid>
                    <title>Dragonfly.Umbraco10.Forms.Web</title>
                    <link>https://marketplace.umbraco.com/package/dragonfly.umbraco10.forms.web</link>
                    <description><![CDATA[A collection of custom Umbraco Forms FieldTypes and Helpers (Umbraco 17&#x2B;) [Full install for website]]]></description>
                    <pubDate>Wed, 15 Jul 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://www.dynamicdave.nl/blog/no-laptop-still-learning-an-umbraco-developers-holiday-checklist/</guid>
                    <title>No Laptop, Still Learning: An Umbraco Developer&#x27;s Holiday Checklist</title>
                    <link>https://www.dynamicdave.nl/blog/no-laptop-still-learning-an-umbraco-developers-holiday-checklist/</link>
                    <description><![CDATA[In a few days, I&#x27;m packing my bags for a holiday, and for the first time in ages, my laptop will stay home. No Visual Studio. No Docker containers spinning up in the background. No sneaky last-minute Git commits. And, honestly, no more of those &quot;let me just fix this one bug real quick&quot; moments.And to be completely honest? I can&#x27;t wait.But that doesn&#x27;t mean I&#x27;m putting my developer brain entirely on pause. If you&#x27;ve been working with Umbraco for years&#x2014;like me&#x2014;you know it&#x27;s much more than a tool you clock in and out of each day. It&#x27;s a community, an ecosystem, and, let&#x27;s be real, a craft that&#x27;s always changing. Even if I don&#x27;t write a line of code, there&#x27;s no shortage of ways to stay inspired and come back from my break with fresh perspectives.Here&#x27;s how I&#x27;m planning to keep the inspiration flowing while away.]]></description>
                    <pubDate>Tue, 14 Jul 2026 22:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://github.com/skybrud/Skybrud.Umbraco.Redirects/releases/tag/v18.0.0-alpha001</guid>
                    <title>Skybrud.Umbraco.Redirects 18.0.0-alpha001</title>
                    <link>https://github.com/skybrud/Skybrud.Umbraco.Redirects/releases/tag/v18.0.0-alpha001</link>
                    <description><![CDATA[Award winning redirects manager for Umbraco.]]></description>
                    <pubDate>Tue, 14 Jul 2026 12:12:30 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/utpro.feature.jobmonitor</guid>
                    <title>uTPro.Feature.JobMonitor</title>
                    <link>https://marketplace.umbraco.com/package/utpro.feature.jobmonitor</link>
                    <description><![CDATA[Read-and-trigger monitor for Umbraco recurring background jobs (Umbraco 16, 17, 18). Adds a Jobs dashboard under the Settings section that lists every recurring background job registered in the site, shows each job&#x27;s timing parameters (period, delay, server roles), records execution telemetry the CMS does not persist natively, estimates the next run, reflects load-balancing and server-role behaviour, and lets an authorized backoffice user trigger a job on demand (&quot;Run now&quot;). Discovers both modern IRecurringBackgroundJob implementations and legacy RecurringHostedServiceBase jobs automatically - no per-job wiring. Read-only by default; the only write is the manual trigger, which runs off the request thread, guards against overlap, and records who initiated it.]]></description>
                    <pubDate>Tue, 14 Jul 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://cornehoskam.com/posts/how-i-upgraded-umbraco-13-to-17-in-less-than-two-hours</guid>
                    <title>How I upgraded Umbraco 13 to 17 in less than two hours!</title>
                    <link>https://cornehoskam.com/posts/how-i-upgraded-umbraco-13-to-17-in-less-than-two-hours</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Sat, 11 Jul 2026 10:19:00 Z</pubDate>
                        <category>blog</category>
                        <category>community</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/flowcourier.umbraco.ai.agents.translation</guid>
                    <title>Flowcourier.Umbraco.AI.Agents.Translation</title>
                    <link>https://marketplace.umbraco.com/package/flowcourier.umbraco.ai.agents.translation</link>
                    <description><![CDATA[Translate whole Umbraco pages in one click &#x2014; every property, nested block content and SEO fields &#x2014; using the AI provider you already configured through Umbraco AI. Every translation lands as a draft and goes through a human approval flow before anything publishes, with reviewer emails, automatic reminders and a Translation Workflow dashboard inside Umbraco&#x27;s Translation section. Free for Umbraco 17.5&#x2B;, including commercial production use.]]></description>
                    <pubDate>Sat, 11 Jul 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/flowcourier.umbraco.ai.agents.seo</guid>
                    <title>Flowcourier.Umbraco.AI.Agents.Seo</title>
                    <link>https://marketplace.umbraco.com/package/flowcourier.umbraco.ai.agents.seo</link>
                    <description><![CDATA[Improve the SEO of any Umbraco page in one click. The SEO Agent reads the open page, works out which properties are SEO and metadata fields &#x2014; even when they have non-standard names &#x2014; and drafts optimised meta titles, descriptions and social fields from the page&#x27;s own content, using the AI provider you already configured through Umbraco AI. Every suggestion is staged into the editor for you to review, edit and Save; nothing is ever written without you. Free for Umbraco 17.5&#x2B;, including commercial production use.]]></description>
                    <pubDate>Sat, 11 Jul 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://www.nevitech.co.uk/blog/migrating-umbraco-13-to-umbraco-17-on-umbraco-cloud/</guid>
                    <title>Migrating Umbraco 13 to Umbraco 17 on Umbraco Cloud</title>
                    <link>https://www.nevitech.co.uk/blog/migrating-umbraco-13-to-umbraco-17-on-umbraco-cloud/</link>
                    <description><![CDATA[A developer guide to upgrading an Umbraco 13 site to Umbraco 17 on Umbraco Cloud by migrating locally and deploying into a fresh Cloud project, covering the full sequence through to a low downtime go live.]]></description>
                    <pubDate>Fri, 10 Jul 2026 23:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://github.com/limbo-works/Limbo.Umbraco.FilterList/releases/tag/v17.0.0-alpha001</guid>
                    <title>Limbo.Umbraco.FilterList 17.0.0-alpha001</title>
                    <link>https://github.com/limbo-works/Limbo.Umbraco.FilterList/releases/tag/v17.0.0-alpha001</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Fri, 10 Jul 2026 15:17:02 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                </item>
                <item>
                    <guid>https://www.nathanielnunes.com/blog/pin-umbraco-docs-version-tampermonkey</guid>
                    <title>Pinning docs.umbraco.com to a Specific Version with Tampermonkey</title>
                    <link>https://www.nathanielnunes.com/blog/pin-umbraco-docs-version-tampermonkey</link>
                    <description><![CDATA[Here is a Tampermonkey userscript that pins docs.umbraco.com to whatever version you are actually working on.]]></description>
                    <pubDate>Fri, 10 Jul 2026 11:30:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://cornehoskam.com/posts/how-i-upgraded-umbraco-13-to-17-in-less-than-two-hours/</guid>
                    <title>How I upgraded Umbraco 13 to 17 in less than two hours!</title>
                    <link>https://cornehoskam.com/posts/how-i-upgraded-umbraco-13-to-17-in-less-than-two-hours/</link>
                    <description><![CDATA[I jumped straight from Umbraco 13 to 17 on Umbraco Cloud in under two hours, TinyMCE to Tiptap and all. Here&#x27;s the full checklist of what I touched.]]></description>
                    <pubDate>Fri, 10 Jul 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/our.umbraco.mediamanager</guid>
                    <title>Our.Umbraco.MediaManager</title>
                    <link>https://marketplace.umbraco.com/package/our.umbraco.mediamanager</link>
                    <description><![CDATA[Safe, async media cleanup for Umbraco 16&#x2013;17: find and remove unused media nodes, duplicates, broken nodes and orphaned physical files, guarded by a deep reference scan, with dry-run preview and Recycle Bin safety.]]></description>
                    <pubDate>Fri, 10 Jul 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://github.com/limbo-works/Limbo.Umbraco.ModelsBuilder/releases/tag/v17.0.0-alpha001</guid>
                    <title>Limbo.Umbraco.ModelsBuilder 17.0.0-alpha001</title>
                    <link>https://github.com/limbo-works/Limbo.Umbraco.ModelsBuilder/releases/tag/v17.0.0-alpha001</link>
                    <description><![CDATA[Limbo.Umbraco.ModelsBuilder is a custom models builder for Umbraco that provides extended functionality compared to Umbraco&#x27;s build-in models builder.]]></description>
                    <pubDate>Thu, 09 Jul 2026 08:05:11 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/geoa.aivisibility</guid>
                    <title>Geoa.AiVisibility</title>
                    <link>https://marketplace.umbraco.com/package/geoa.aivisibility</link>
                    <description><![CDATA[Make your Umbraco site visible to AI answer engines (ChatGPT, Perplexity, Gemini). Geoa injects registry-verified Organization schema (DK / NO / SE / FI), FAQ and Article JSON-LD, and an optional llms.txt file, then scores every page for answer-engine readiness. Track E-E-A-T signals, build citation corroboration (sameAs), and see which AI crawlers visit your site &#x2014; all from a native backoffice dashboard, powered by the Geoa platform.]]></description>
                    <pubDate>Thu, 09 Jul 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.automate.inspector</guid>
                    <title>Umbraco.Community.Automate.Inspector</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.automate.inspector</link>
                    <description><![CDATA[Package Description]]></description>
                    <pubDate>Thu, 09 Jul 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.uibuilder.automate</guid>
                    <title>Umbraco.UIBuilder.Automate</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.uibuilder.automate</link>
                    <description><![CDATA[Umbraco UI Builder triggers and actions for Umbraco Automate]]></description>
                    <pubDate>Thu, 09 Jul 2026 00:00:00 Z</pubDate>
                        <category>hq</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.automate.slack</guid>
                    <title>Umbraco.Automate.Slack</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.automate.slack</link>
                    <description><![CDATA[Slack connection and actions for Umbraco Automate]]></description>
                    <pubDate>Thu, 09 Jul 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://owain.codes/blog/2026/july/are-you-okay/</guid>
                    <title>Are you okay</title>
                    <link>https://owain.codes/blog/2026/july/are-you-okay/</link>
                    <description><![CDATA[On men, mental health, and the communities that keep us going, in a job AI is quietly rewriting.]]></description>
                    <pubDate>Thu, 09 Jul 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://skttl.dev/blog/go-to-partial/</guid>
                    <title>Make Razor Partials Navigable in VS Code</title>
                    <link>https://skttl.dev/blog/go-to-partial/</link>
                    <description><![CDATA[A small VS Code extension that adds Go to Definition and live diagnostics for Razor partial view references in .cshtml files.]]></description>
                    <pubDate>Thu, 09 Jul 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://umbraco.com/blog/launching-umbraco-automate/</guid>
                    <title>Launching Umbraco Automate</title>
                    <link>https://umbraco.com/blog/launching-umbraco-automate/</link>
                    <description><![CDATA[Streamline your CMS workflows with Umbraco Automate. Create unlimited drag-and-drop automations, triggers, and AI tool integrations in Umbraco 17&#x2B;.]]></description>
                    <pubDate>Thu, 09 Jul 2026 00:00:00 Z</pubDate>
                        <category>hq</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://hayleymarkdigital.co.uk/blog/exploring-umbraco-ai-for-end-users/</guid>
                    <title>Exploring Umbraco AI for end users</title>
                    <link>https://hayleymarkdigital.co.uk/blog/exploring-umbraco-ai-for-end-users/</link>
                    <description><![CDATA[Providing reliable, proactive and personable freelance support for website updates, SEO, lead generation and ongoing marketing strategies.]]></description>
                    <pubDate>Thu, 09 Jul 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://dev.to/chaudharidevam/why-we-pair-nextjs-with-umbraco-17--842</guid>
                    <title>Why We Pair Next.js with Umbraco 17 ?</title>
                    <link>https://dev.to/chaudharidevam/why-we-pair-nextjs-with-umbraco-17--842</link>
                    <description><![CDATA[&lt;p&gt;When building a content-driven website, there are two goals that are often in tension: give visitors a fast, modern, SEO-friendly site, and give the content team a CMS they can actually use without calling a developer every time a page needs to change.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Our answer is to split the problem in two and let each half of the stack do what it&#x27;s best at:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;strong&gt;Umbraco 17&lt;/strong&gt;, running on &lt;strong&gt;.NET 10&lt;/strong&gt;, as the content backend&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;strong&gt;Next.js 16&lt;/strong&gt; with &lt;strong&gt;React 19&lt;/strong&gt;, running on the App Router, as the presentation layer&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;Here&#x27;s why we made that call, and how it plays out in practice.&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  Two apps, one clean contract&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Rather than bolting a headless CMS onto an existing site, we build the two halves as genuinely independent applications that only talk to each other over HTTP:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;The Umbraco installation is the backoffice, the content types, the media library, the database. This is where content editors log in, build pages out of reusable blocks, and manage content like blog posts.&lt;/li&gt;&#xA;&lt;li&gt;The Next.js app is a standalone frontend. It never touches the Umbraco database directly, every piece of content it renders comes from an HTTP call.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;That separation is the whole point of a &quot;headless&quot; CMS: the people managing content and the people managing the website&#x27;s code can move independently. CMS upgrades don&#x27;t require a frontend deploy, and frontend releases don&#x27;t require touching the CMS.&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  The content pipeline: Umbraco&#x27;s Delivery API&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Umbraco 17 ships with a Content Delivery API a built-in, versioned JSON API that exposes published content without any custom plumbing. We lean on it heavily rather than building a bespoke API from scratch, which saves real development time.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;A page fetch from Next.js looks like this in practice:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight http&quot;&gt;&lt;code&gt;&lt;span class=&quot;err&quot;&gt;GET /umbraco/delivery/api/v2/content/item/home?expand=properties[$all[properties[$all[properties[$all]]]]]&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;That &lt;code&gt;expand&lt;/code&gt; parameter is doing a lot of work: pages are built by editors dragging and dropping content blocks (hero sections, feature grids, image-and-text panels, calls to action) using Umbraco&#x27;s Block Grid editor, and those blocks can be nested. The expansion query lets us pull an entire page blocks inside blocks inside blocks in a single round trip instead of chasing references with follow-up requests.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;On the Next.js side, a small typed fetch helper wraps every one of these calls, attaches an API key, and lets Next&#x27;s own data cache handle short-lived revalidation. There&#x27;s no GraphQL client, no heavyweight SDK just &lt;code&gt;fetch()&lt;/code&gt;, TypeScript types that mirror the Umbraco content model, and a short cache window so published changes show up almost immediately without hammering the CMS on every request.&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  Rendering: server-rendered, block by block&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Generic content pages funnel through a single catch-all route that renders server-side on each request. Instead of one big template, rendering is driven by content type: a dispatcher component looks at what kind of block came back from Umbraco a feature section, an image gallery, a testimonial, a two-column layout and hands it off to the matching React component.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The effect is that adding a new content block is mostly a two-sided change: define the element type in Umbraco, add a matching case in the renderer. Editors get a new building block to compose pages with; developers don&#x27;t have to build new pages from scratch every time a new layout is needed.&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  Beyond the CMS defaults&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;The Delivery API covers page content well, but a few features need more than &quot;fetch a page and render it&quot;:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;strong&gt;Filtering and search.&lt;/strong&gt; Category pages, tag pages, and &quot;previous/next&quot; navigation are backed by custom API endpoints that walk the content tree directly, and free-text search runs on Umbraco&#x27;s built-in Lucene-based indexer rather than an external search service. That avoids standing up and paying for a separate search product just to let visitors search content.&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;strong&gt;Forms.&lt;/strong&gt; Submissions are validated in the browser, sent through a Next.js API route, and stored by a small custom endpoint on the Umbraco side with a lightweight dashboard added to the Umbraco backoffice so the team can review submissions without leaving the CMS they already use every day.&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;strong&gt;Media handling.&lt;/strong&gt; Images uploaded into Umbraco&#x27;s media library are served through Next.js&#x27;s image optimizer, so editors don&#x27;t need to think about responsive image sizes or formats that&#x27;s handled automatically on the way out.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  What this stack gets you&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Putting it together, the architecture gives:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;strong&gt;Speed&lt;/strong&gt;, from server rendering and Next.js&#x27;s image and asset optimization&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;strong&gt;SEO control that lives with content&lt;/strong&gt;, since page titles, descriptions, and indexing rules are authored directly in Umbraco and flow straight into page metadata no separate SEO tooling to keep in sync&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;strong&gt;A content team that isn&#x27;t blocked by developers&lt;/strong&gt;, because new pages are built from existing blocks rather than new code&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;strong&gt;A frontend that isn&#x27;t blocked by the CMS release cycle&lt;/strong&gt;, because the two halves deploy independently&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  Trade-offs worth naming&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Being candid, this approach isn&#x27;t free. Running on Umbraco 17 and Next.js 16 means running close to the front of both ecosystems fewer battle-tested examples to lean on, but a stack that stays current for years rather than needing a rewrite in one. And a headless setup means CMS preview/draft workflows, sitemaps, and secrets/hosting management all need to be built or configured deliberately they don&#x27;t come for free just because the CMS has them out of the box in a traditional, non-headless setup.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;For a site with a real content operation behind it, splitting &quot;where content lives&quot; from &quot;how it&#x27;s presented&quot; is worth the extra moving part. It lets each side of the team content and engineering work at their own pace, without waiting on each other.&lt;/p&gt;]]></description>
                    <pubDate>Wed, 08 Jul 2026 07:49:11 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.drafts</guid>
                    <title>Umbraco.Community.Drafts</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.drafts</link>
                    <description><![CDATA[Auto-save your work as you go, just like Gmail. Never lose your edits again.]]></description>
                    <pubDate>Wed, 08 Jul 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.linkaudit</guid>
                    <title>Umbraco.Community.LinkAudit</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.linkaudit</link>
                    <description><![CDATA[A lightweight, single-purpose link auditor for Umbraco. Scans published content on a schedule (or on demand), reports broken external links and links that point at hosts you would rather keep internal &#x2014; all from a read-only backoffice dashboard. Reads the content cache directly rather than crawling the rendered site.]]></description>
                    <pubDate>Wed, 08 Jul 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://www.dynamicdave.nl/blog/umbraco-18-elements/</guid>
                    <title>Umbraco 18 Finally gives reusable content the home it deserves</title>
                    <link>https://www.dynamicdave.nl/blog/umbraco-18-elements/</link>
                    <description><![CDATA[There are flashy features that get everyone excited&#x2014;new editors, AI integrations, shiny dashboards. They look great in a keynote and are fun to show off. But then there are those features that, quietly, just fix long-standing headaches. For me, the new Library and Elements in Umbraco 18 are absolutely in that second group.When I first saw these demoed at Codegarden, I immediately thought, &quot;Here we go. This is definitely going to be one of my favorite updates since a long time.&quot; It&#x27;s not a brand-new idea. In fact, it&#x27;s almost more impressive because it turns something most experienced Umbraco developers have hacked together themselves into an actual, official feature.If you&#x2019;ve built Umbraco websites for any length of time, you&#x2019;ve probably done this: made a &#x201C;Globals &#x201C; of &#x201C;Various Content&#x201D; node and hidden it, set up a Shared Content folder, tossed reusable stuff onto a Settings page, or kept a folder with call-to-actions, testimonials, author profiles, or banners. None of which are even real pages.Did it work? Yeah&#x2026; most of the time. But let&#x27;s be honest&#x2014;it always felt like a kludge.That kind of content never really belonged alongside website pages. This &#x201C;content&#x201D; didn&#x2019;t need URLs; users weren&#x2019;t supposed to visit it. We only structured things this way because editors needed somewhere to manage reusable pieces. For years, we just pretended these were documents because Umbraco left us no other option.With Umbraco 18, the compromise disappears.]]></description>
                    <pubDate>Tue, 07 Jul 2026 22:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://umbracocommunity.social/@UmbHost/116877874250829198</guid>
                    <title>UmbHost GreenStack&#x27;s UK is now live!</title>
                    <link>https://umbracocommunity.social/@UmbHost/116877874250829198</link>
                    <description><![CDATA[&#x1F33F;&#x1F1EC;&#x1F1E7;&#x1F680; GreenStack&#x27;s UK is now live! &#x1F33F;&#x1F1EC;&#x1F1E7;&#x1F680; Our most requested feature since the January launch! Full UK data residency for Umbraco hosting! Files, databases, and backups all stay in the UK, served from our new London infrastructure. All package tiers (Core, Pro, and Scale) are available from day one, with the same pricing as the EU region. If data residency has been holding you back, that barrier is gone &#x1F4A5; https://umbhost.net/blog/2026/07/greenstack-comes-home-uk-region-now-available#Umbraco #Hosting #GreenStack]]></description>
                    <pubDate>Tue, 07 Jul 2026 15:54:09 Z</pubDate>
                        <category>community</category>
                        <category>social</category>
                        <category>mastodon</category>
                </item>
                <item>
                    <guid>https://skrift.io/issues/#129</guid>
                    <title>Skrift Issue #129</title>
                    <link>https://skrift.io/issues/#129</link>
                    <description><![CDATA[Featuring guest posts by Bogdan Kosarevskyi on &quot;The tip of the observability iceberg: depth is not measured in meters, but in levels of observation&quot; and Hubert Galuszka on &quot;Virtual Members: Passwordless Umbraco Auth Without the Identity-Provider Bill&quot;]]></description>
                    <pubDate>Tue, 07 Jul 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                        <category>skrift</category>
                </item>
                <item>
                    <guid>https://umbraco.com/blog/security-advisory-july-7-2026-security-patches-are-now-available/</guid>
                    <title>Security Advisory, July 7, 2026: Security Patches are now available</title>
                    <link>https://umbraco.com/blog/security-advisory-july-7-2026-security-patches-are-now-available/</link>
                    <description><![CDATA[Summary: A vulnerability classified as high has been found and fixed in Umbraco 13, 17, and 18.]]></description>
                    <pubDate>Tue, 07 Jul 2026 00:00:00 Z</pubDate>
                        <category>hq</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://umbraco.com/blog/uprofile-july-2026-georgina-bidder/</guid>
                    <title>uProfile July 2026 - Georgina Bidder</title>
                    <link>https://umbraco.com/blog/uprofile-july-2026-georgina-bidder/</link>
                    <description><![CDATA[Meet Georgina: From the deep end to the Codegarden stage: Meet Core Collaborator Georgina Bidder!]]></description>
                    <pubDate>Tue, 07 Jul 2026 00:00:00 Z</pubDate>
                        <category>hq</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/thtaai</guid>
                    <title>ThtaAi</title>
                    <link>https://marketplace.umbraco.com/package/thtaai</link>
                    <description><![CDATA[AI-powered content generation for the Umbraco backoffice. Uses a local LLM (or other LLM API) to generate page content, block content, and full pages from natural-language prompts, with editorial review before anything publishes.]]></description>
                    <pubDate>Tue, 07 Jul 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://github.com/abjerner/Limbo.Umbraco.TextBox/releases/tag/v17.0.0-alpha001</guid>
                    <title>Limbo.Umbraco.TextBox 17.0.0-alpha001</title>
                    <link>https://github.com/abjerner/Limbo.Umbraco.TextBox/releases/tag/v17.0.0-alpha001</link>
                    <description><![CDATA[Limbo Textbox&#xA0;(or&#xA0;Limbo.Umbraco.TextBox) is a package that adds new textbox and textarea property editors for Umbraco 10&#x2B;. While having similar functionality to the build in property editors, this package adds a few extra features.]]></description>
                    <pubDate>Mon, 06 Jul 2026 11:46:55 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                </item>
                <item>
                    <guid>https://marathonus.com/about/blog/what-umbraco-codegarden-2026-left-on-me-permanently/</guid>
                    <title>What Umbraco Codegarden 2026 Left on Me&amp;#x2014;Permanently | Marathon Consulting</title>
                    <link>https://marathonus.com/about/blog/what-umbraco-codegarden-2026-left-on-me-permanently/</link>
                    <description><![CDATA[Marathon&#x27;s Scott Clevenger reflects on Umbraco Codegarden 2026 &amp;#x2014; an MVP, a tattoo, and a platform that&#x27;s ready for whatever comes next.]]></description>
                    <pubDate>Mon, 06 Jul 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://www.linkedin.com/pulse/ai-signalling-end-cms-we-know-simply-becoming-much-bigger-durrant-z3nme/</guid>
                    <title>Is AI signalling the end of the CMS as we know it? Or is it simply becoming something much bigger?</title>
                    <link>https://www.linkedin.com/pulse/ai-signalling-end-cms-we-know-simply-becoming-much-bigger-durrant-z3nme/</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Mon, 06 Jul 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://gibe.digital/blog/gibe-goes-to-codegarden-2026-edition/</guid>
                    <title>Gibe goes to Codegarden (2026 edition)</title>
                    <link>https://gibe.digital/blog/gibe-goes-to-codegarden-2026-edition/</link>
                    <description><![CDATA[Gibe reflects on Codegarden 2026, covering the latest Umbraco announcements, standout sessions, community highlights, and our Package Award nomination.]]></description>
                    <pubDate>Mon, 06 Jul 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://owainjones.dev/blog/new-giscus-powered-comments-and-h5yr-widget/</guid>
                    <title>New Giscus powered comments and H5YR widget!</title>
                    <link>https://owainjones.dev/blog/new-giscus-powered-comments-and-h5yr-widget/</link>
                    <description><![CDATA[I&amp;#x27;ve added a giscus powered comments, and the awesome H5YR widget, to my blog posts!]]></description>
                    <pubDate>Sat, 04 Jul 2026 19:18:36 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://www.nevitech.co.uk/blog/introducing-imagesharp-trimcache-for-umbraco/</guid>
                    <title>Introducing ImageSharp TrimCache for Umbraco</title>
                    <link>https://www.nevitech.co.uk/blog/introducing-imagesharp-trimcache-for-umbraco/</link>
                    <description><![CDATA[A free Umbraco package that trims the ImageSharp.Web image cache by age on a schedule, for both the local physical cache and Azure Blob storage. Stop the media cache growing unbounded on Umbraco Cloud and self hosted sites.]]></description>
                    <pubDate>Fri, 03 Jul 2026 23:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://shazwazza.com/post/letting-ai-agents-loose-on-examine/</guid>
                    <title>Letting AI agents loose on Examine</title>
                    <link>https://shazwazza.com/post/letting-ai-agents-loose-on-examine/</link>
                    <description><![CDATA[I&#x27;ve been maintaining Examine for a very long time now. It&#x27;s the search and indexing library that sits underneath every Umbraco site, and like any project that&#x27;s been around long enough, it has plenty of hot paths that could be faster, a steady trickle of issues that need triaging, and a backlog of &quot;I&#x27;ll get to that eventually&quot; performance work that, well&#x2026; I never actually get to.&#xA;So a couple of months ago I thought I&#x27;d try an experiment - what if I stopped doing all of that myself and instead let a bunch of AI agents do it for me, on a schedule, while I got on with everything else? This post is about how that went. I&#x27;ve shipped a few releases off the back of it and some of the hot-path improvements are genuinely a bit ridiculous.&#xA;So what are these &quot;agentic workflows&quot;?&#xA;The thing I installed is GitHub Next&#x27;s Agentic Workflows - a set of markdown-defined workflows that run in GitHub Actions and drive an AI agent to do actual maintenance work on your repo. They&#x27;re not chat bots. They run on a schedule, they have persistent memory, they open real pull requests, and they leave the &quot;should this ship?&quot; decision to me.&#xA;I ended up with a few of them running on Examine:&#xA;&#xA;Perf Improver - runs daily, hunts for performance bottlenecks, writes benchmarks to actually prove the improvement, and opens a draft PR with the before/after numbers.&#xA;Efficiency Improver - its scrappier sibling, focused on the smaller allocation-and-LINQ-state-machine wins that add up over time.&#xA;Daily Issue Triage - goes through untriaged issues, sets types, applies labels, spots duplicates, and leaves a tidy triage report for me.&#xA;Agentic Maintenance - keeps the whole setup ticking along.&#xA;&#xA;Each one is just a markdown file in .github/workflows/ with a description, a schedule, some safe-outputs limits (things like &quot;you may open at most 4 PRs per run, and they must be drafts&quot;) and a big prompt describing how to behave. That&#x27;s it. The nice part is that the guardrails are declarative, so the agent can&#x27;t merge its own PRs, it can&#x27;t touch protected files, and it can only comment so many times per run. All of that is baked in.&#xA;How it actually works day to day&#xA;The bit that makes this more than a gimmick is the persistent memory. Every run, the Perf Improver reads its own notes - which build/test/benchmark commands it validated, what&#x27;s on its optimisation backlog, what it worked on last time, and which suggestions I&#x27;ve already ticked off. Then it does a couple of tasks in a round-robin fashion so it&#x27;s not endlessly poking at the same corner of the codebase.&#xA;It also keeps a single rolling &quot;Monthly Activity&quot; issue open with a checklist of what needs my attention. So my side of it is pretty simple: the agent opens a draft PR with measured before/after numbers, I read it and run CI, and if I&#x27;m happy with it I merge. That&#x27;s the whole loop. I&#x27;m the reviewer, the agent is the workhorse doing the grind I never had time for.&#xA;So what did they actually get done?&#xA;Over roughly the last two months, here&#x27;s what these workflows actually got up to on Examine:&#xA;&#xA;124 successful Perf Improver runs and 9 successful Efficiency Improver runs&#xA;20 successful Daily Issue Triage runs quietly keeping the issue tracker tidy&#xA;24 performance/efficiency PRs reviewed and merged (13 from Perf Improver, 11 from Efficiency Improver) between late May and the end of June&#xA;And the bit that actually matters - three releases shipped off this work: v3.8.0, v3.9.0 and the v4.0.0-beta.7 pre-release&#xA;&#xA;That last point is really the whole thing. This isn&#x27;t a pile of speculative branches rotting in a fork somewhere - it&#x27;s code that went through my review, passed CI, and is now sitting in NuGet packages that real Umbraco sites are running.&#xA;Show me the numbers&#xA;Right, this is the part I actually get excited about. One of my favourite things about the Perf Improver is that its prompt tells it to only attempt improvements it can actually measure - establish a baseline first, make the change, then measure again and document both numbers. For the algorithmic hot-path stuff that means benchmarks, so along the way it built out a proper BenchmarkDotNet suite that compares the current source against the published NuGet packages (3.0.1 through 3.3.0), which means I can show you real, reproducible deltas instead of hand waving.&#xA;The full-text search hot path&#xA;ManagedQuery is the primary full-text search entry point in Examine - it&#x27;s what runs on basically every search. The agent noticed it had no dedicated benchmark, wrote one, and then stacked up a series of small, individually measured changes: a volatile factory cache in SearchContext.GetFieldValueType, an early return in the extract-terms check, and killing off some redundant ConcurrentDictionary lookups in AddDocument.&#xA;Here&#x27;s the current source vs the most recent 3.3.0 release, on a 1,000-document index:&#xA;&#xA;&#xA;&#xA;Method&#xA;Version&#xA;Mean&#xA;Allocated&#xA;&#xA;&#xA;&#xA;&#xA;ManagedQueryAllFields&#xA;3.3.0&#xA;11.42 ms&#xA;1,323 KB&#xA;&#xA;&#xA;ManagedQueryAllFields&#xA;Source&#xA;2.17 ms&#xA;371 KB&#xA;&#xA;&#xA;&#xA;That&#x27;s about 5.3x faster and roughly 3.6x less memory allocated on the single most travelled code path in the whole library. On the busiest thing Examine does. I&#x27;ll happily take that.&#xA;Building queries&#xA;GroupedAnd / GroupedOr / GroupedNot are the workhorses of the query builder. A little string[] fast-path (skipping a defensive .ToArray() copy when the caller already handed it a string[]) plus some allocation trimming got this:&#xA;&#xA;&#xA;&#xA;Method&#xA;Version&#xA;Mean&#xA;Allocated&#xA;&#xA;&#xA;&#xA;&#xA;CreateQueryOnly&#xA;3.3.0&#xA;3,995 ns&#xA;8.34 KB&#xA;&#xA;&#xA;CreateQueryOnly&#xA;Source&#xA;319 ns&#xA;2.20 KB&#xA;&#xA;&#xA;GroupedAndStringArray&#xA;3.3.0&#xA;21,377 ns&#xA;21.10 KB&#xA;&#xA;&#xA;GroupedAndStringArray&#xA;Source&#xA;16,659 ns&#xA;14.34 KB&#xA;&#xA;&#xA;&#xA;The CreateQuery() baseline dropping from 8.34 KB down to 2.2 KB is a lovely little win, and the grouped clauses are about 25% faster with a third of the allocation shaved off.&#xA;Constructing a ValueSet&#xA;Every single document you index goes through a ValueSet constructor. The old path allocated an intermediate dictionary and a generator state machine per field, which is exactly the kind of thing you don&#x27;t notice until you&#x27;re bulk indexing a big site. The agent got rid of both:&#xA;&#xA;&#xA;&#xA;Method&#xA;Version&#xA;Mean&#xA;Allocated&#xA;&#xA;&#xA;&#xA;&#xA;FromDictionary5Fields&#xA;3.3.0&#xA;1,183 ns&#xA;2,200 B&#xA;&#xA;&#xA;FromDictionary5Fields&#xA;Source&#xA;226 ns&#xA;592 B&#xA;&#xA;&#xA;FromDictionary20Fields&#xA;3.3.0&#xA;4,007 ns&#xA;6,544 B&#xA;&#xA;&#xA;FromDictionary20Fields&#xA;Source&#xA;654 ns&#xA;1,520 B&#xA;&#xA;&#xA;&#xA;That&#x27;s roughly 5-6x faster and about 4x less allocated on indexing, and when you&#x27;re rebuilding the index on a large Umbraco site that adds up fast.&#xA;The really nice touch is that these benchmark result tables now live in &lt;remarks&gt; doc-comments right next to the benchmark code, so the numbers are versioned in the repo alongside the thing they measure. The agent did that bit too.&#xA;Was it actually worth it?&#xA;For me the thing that makes it work is the measurement. Everything comes to me as a small, focused, draft PR with the numbers attached, so I can look at it, sanity check it, run CI, and decide in a couple of minutes. It&#x27;s not zero effort - I still read every change before it goes anywhere near main - but the ratio is fantastic. I&#x27;m getting a steady stream of well-measured, single-purpose performance PRs on a library I care about, on paths I&#x27;d genuinely never have found the time to optimise by hand, and I&#x27;ve shipped real releases because of it. For a project I maintain around everything else, that&#x27;s a pretty great deal.&#xA;If you maintain a repo with a backlog you never get to, especially performance work that needs benchmarks to justify it, I&#x27;d recommend giving GitHub Next&#x27;s agentics a go.&#xA;You can see all of it out in the open on the Examine repo - the [perf-improver] and [efficiency-improver] PRs, the benchmark suite, and the releases they fed into. And there&#x27;s a nice bonus here for me too: ExamineX, my managed, cloud-hosted Examine search offering, runs on this exact same internal plumbing. So all this work the agents have been doing to tighten up Examine&#x27;s query and indexing hot paths feeds straight through into ExamineX - the underlying engine gets faster and leaner, and every ExamineX site gets those wins for free without changing a thing. If you&#x27;d rather have your search running as a managed service instead of hosting Lucene indexes on your own servers, that&#x27;s what ExamineX is there for. &#x1F642;]]></description>
                    <pubDate>Fri, 03 Jul 2026 17:45:20 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://github.com/limbo-works/Limbo.Umbraco.Tables/releases/tag/v17.0.0-alpha001</guid>
                    <title>Limbo.Umbraco.Tables 17.0.0-alpha001</title>
                    <link>https://github.com/limbo-works/Limbo.Umbraco.Tables/releases/tag/v17.0.0-alpha001</link>
                    <description><![CDATA[Limbo.Umbraco.Tables is a package for Umbraco featuring property editor for building table based content.]]></description>
                    <pubDate>Fri, 03 Jul 2026 12:56:06 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                </item>
                <item>
                    <guid>https://medium.com/@ravimotha/umbraco-london-july-meetup-the-write-up-b4ce49a37390?source=rss-8e76be83b03f------2</guid>
                    <title>Umbraco London July Meetup .. the write- up</title>
                    <link>https://medium.com/@ravimotha/umbraco-london-july-meetup-the-write-up-b4ce49a37390?source=rss-8e76be83b03f------2</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Fri, 03 Jul 2026 09:18:14 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://medium.com/@ravimotha/umbraco-london-july-meetup-the-write-up-b4ce49a37390?source=rss------umbraco-5</guid>
                    <title>Umbraco London July Meetup .. the write- up</title>
                    <link>https://medium.com/@ravimotha/umbraco-london-july-meetup-the-write-up-b4ce49a37390?source=rss------umbraco-5</link>
                    <description><![CDATA[&lt;div class=&quot;medium-feed-item&quot;&gt;&lt;p class=&quot;medium-feed-image&quot;&gt;&lt;a href=&quot;https://medium.com/@ravimotha/umbraco-london-july-meetup-the-write-up-b4ce49a37390?source=rss------umbraco-5&quot;&gt;&lt;img src=&quot;https://cdn-images-1.medium.com/max/2600/1*TzZ8HkxpsC1nIL1zJpZFjA@2x.jpeg&quot; width=&quot;4624&quot;&gt;&lt;/a&gt;&lt;/p&gt;&lt;p class=&quot;medium-feed-snippet&quot;&gt;Umbraco london is trying something silly a short unprogrammed stream of useless brain fog.&lt;/p&gt;&lt;p class=&quot;medium-feed-link&quot;&gt;&lt;a href=&quot;https://medium.com/@ravimotha/umbraco-london-july-meetup-the-write-up-b4ce49a37390?source=rss------umbraco-5&quot;&gt;Continue reading on Medium &#xBB;&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;]]></description>
                    <pubDate>Fri, 03 Jul 2026 09:18:14 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://mattbrailsford.dev/creating-a-safe-space-for-editors-to-be-wrong</guid>
                    <title>Creating A Safe Space for Editors to Be Wrong</title>
                    <link>https://mattbrailsford.dev/creating-a-safe-space-for-editors-to-be-wrong</link>
                    <description><![CDATA[I spend most of my time these days working on Umbraco AI, bringing AI into the hands of content editors. So I think a lot about what actually makes...]]></description>
                    <pubDate>Fri, 03 Jul 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/phases.umbraco.contentsearch</guid>
                    <title>Phases.Umbraco.ContentSearch</title>
                    <link>https://marketplace.umbraco.com/package/phases.umbraco.contentsearch</link>
                    <description><![CDATA[Advanced content search for the Umbraco backoffice. Editors can search content by document type and property, view results in a sortable grid, export to CSV or Excel, and save searches for later.]]></description>
                    <pubDate>Fri, 03 Jul 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://www.youtube.com/watch?v=X8im857dhUs</guid>
                    <title>UMBRAAD 2026 | Accessibility Manual Testing: Why Lived Experience Matters - Thiago Carmo</title>
                    <link>https://www.youtube.com/watch?v=X8im857dhUs</link>
                    <description><![CDATA[Accessibility Manual Testing: Why Lived Experience Matters by Thiago Carmo&#xA;&#xA;UMBRAAD is a free virtual Umbraco community event packed with practical talks, live demos, and expert Q&amp;A sessions on building a more inclusive web.&#xA;&#xA;Read more on https://umbraad.com]]></description>
                    <pubDate>Thu, 02 Jul 2026 07:48:53 Z</pubDate>
                        <category>community</category>
                        <category>youtube</category>
                </item>
                <item>
                    <guid>https://www.youtube.com/watch?v=AsKGl8N20ek</guid>
                    <title>UMBRAAD 2026 | Accessibility Debt in Digital Products - Shivansh Mathur</title>
                    <link>https://www.youtube.com/watch?v=AsKGl8N20ek</link>
                    <description><![CDATA[Accessibility Debt in Digital Products: What AI Fixes and What It Doesn&#x27;t by Shivansh Mathur&#xA;&#xA;UMBRAAD is a free virtual Umbraco community event packed with practical talks, live demos, and expert Q&amp;A sessions on building a more inclusive web.&#xA;&#xA;Read more on https://umbraad.com]]></description>
                    <pubDate>Thu, 02 Jul 2026 07:28:49 Z</pubDate>
                        <category>community</category>
                        <category>youtube</category>
                </item>
                <item>
                    <guid>https://www.youtube.com/watch?v=on7fwoS32Hs</guid>
                    <title>UMBRAAD 2026 | Write Once, Reach Everyone: Accessible Writing - Corey Vilhauer</title>
                    <link>https://www.youtube.com/watch?v=on7fwoS32Hs</link>
                    <description><![CDATA[Write Once, Reach Everyone: Accessible Writing and GEO Want the Same Solution by Corey Vilhauer&#xA;&#xA;UMBRAAD is a free virtual Umbraco community event packed with practical talks, live demos, and expert Q&amp;A sessions on building a more inclusive web.&#xA;&#xA;Read more on https://umbraad.com]]></description>
                    <pubDate>Thu, 02 Jul 2026 07:24:46 Z</pubDate>
                        <category>community</category>
                        <category>youtube</category>
                </item>
                <item>
                    <guid>https://www.youtube.com/watch?v=FwgBVdGi3mw</guid>
                    <title>UMBRAAD 2026 | Why Automated Accessibility Tools Are Not Enough - Shadrack William Kyei</title>
                    <link>https://www.youtube.com/watch?v=FwgBVdGi3mw</link>
                    <description><![CDATA[Why Automated Accessibility Tools Are Not Enough by Shadrack William Kyei&#xA;&#xA;UMBRAAD is a free virtual Umbraco community event packed with practical talks, live demos, and expert Q&amp;A sessions on building a more inclusive web.&#xA;&#xA;Read more on https://umbraad.com]]></description>
                    <pubDate>Thu, 02 Jul 2026 07:19:35 Z</pubDate>
                        <category>community</category>
                        <category>youtube</category>
                </item>
                <item>
                    <guid>https://www.youtube.com/watch?v=Oa6Y7u3qITo</guid>
                    <title>UMBRAAD 2026 | What No One Tells You About Working in Accessibility - Danny Lancaster</title>
                    <link>https://www.youtube.com/watch?v=Oa6Y7u3qITo</link>
                    <description><![CDATA[What No One Tells You About Working in Accessibility by Danny Lancaster&#xA;&#xA;UMBRAAD is a free virtual Umbraco community event packed with practical talks, live demos, and expert Q&amp;A sessions on building a more inclusive web.&#xA;&#xA;Read more on https://umbraad.com]]></description>
                    <pubDate>Thu, 02 Jul 2026 07:16:46 Z</pubDate>
                        <category>community</category>
                        <category>youtube</category>
                </item>
                <item>
                    <guid>https://www.youtube.com/watch?v=1tUY7i2mKI4</guid>
                    <title>UMBRAAD 2026 | Shift Left on Accessibility: Beyond the Audit - Ramona Domen</title>
                    <link>https://www.youtube.com/watch?v=1tUY7i2mKI4</link>
                    <description><![CDATA[Shift Left on Accessibility: Beyond the Audit by Ramona Domen&#xA;&#xA;UMBRAAD is a free virtual Umbraco community event packed with practical talks, live demos, and expert Q&amp;A sessions on building a more inclusive web.&#xA;&#xA;Read more on https://umbraad.com]]></description>
                    <pubDate>Thu, 02 Jul 2026 07:13:10 Z</pubDate>
                        <category>community</category>
                        <category>youtube</category>
                </item>
                <item>
                    <guid>https://www.youtube.com/watch?v=spFK0VODBiI</guid>
                    <title>UMBRAAD 2026 | Designing for cognition - Ellie Barrett</title>
                    <link>https://www.youtube.com/watch?v=spFK0VODBiI</link>
                    <description><![CDATA[Designing for cognition by Ellie Barrett&#xA;&#xA;UMBRAAD is a free virtual Umbraco community event packed with practical talks, live demos, and expert Q&amp;A sessions on building a more inclusive web.&#xA;&#xA;Read more on https://umbraad.com]]></description>
                    <pubDate>Thu, 02 Jul 2026 07:05:11 Z</pubDate>
                        <category>community</category>
                        <category>youtube</category>
                </item>
                <item>
                    <guid>https://www.youtube.com/watch?v=dStALum-g_k</guid>
                    <title>UMBRAAD 2026 | Automating Accessibility Audits - Jordan Smith</title>
                    <link>https://www.youtube.com/watch?v=dStALum-g_k</link>
                    <description><![CDATA[Automating Accessibility Audits: Building a Full-Pipeline A11Y Scanning &amp; Reporting Tool by Jordan Smith.&#xA;&#xA;UMBRAAD is a free virtual Umbraco community event packed with practical talks, live demos, and expert Q&amp;A sessions on building a more inclusive web.&#xA;&#xA;Read more on https://umbraad.com]]></description>
                    <pubDate>Thu, 02 Jul 2026 07:00:43 Z</pubDate>
                        <category>community</category>
                        <category>youtube</category>
                </item>
                <item>
                    <guid>https://www.youtube.com/watch?v=IRYNePlevSo</guid>
                    <title>UMBRAAD 2026 | Accessibility starts before the software - Carl Sargunar</title>
                    <link>https://www.youtube.com/watch?v=IRYNePlevSo</link>
                    <description><![CDATA[Accessibility starts before the software: hardware, cloud tooling, LLMs and diminishing returns by Carl Sargunar.&#xA;&#xA;UMBRAAD is a free virtual Umbraco community event packed with practical talks, live demos, and expert Q&amp;A sessions on building a more inclusive web.&#xA;&#xA;Read more on https://umbraad.com]]></description>
                    <pubDate>Thu, 02 Jul 2026 06:44:05 Z</pubDate>
                        <category>community</category>
                        <category>youtube</category>
                </item>
                <item>
                    <guid>https://www.dutchumbracoalliance.nl/en</guid>
                    <title>Dutch Umbraco Alliance Festival, a new festival on september 22 in the netherlands.</title>
                    <link>https://www.dutchumbracoalliance.nl/en</link>
                    <description><![CDATA[Dutch Umbraco Alliance Festival, a new festival on september 22 in the netherlands. We like to get a lot of people.]]></description>
                    <pubDate>Thu, 02 Jul 2026 05:29:39 Z</pubDate>
                        <category>community</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/ideo.umbraco.mediamanager</guid>
                    <title>Ideo.Umbraco.MediaManager</title>
                    <link>https://marketplace.umbraco.com/package/ideo.umbraco.mediamanager</link>
                    <description><![CDATA[Safe, async media cleanup for Umbraco v17: find and remove orphaned media nodes and orphaned physical files, guarded by a deep reference scan, with dry-run preview and Recycle Bin safety.]]></description>
                    <pubDate>Thu, 02 Jul 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://umbraco.com/blog/the-agent-ready-cms-enable-the-ecosystem-umbraco-s-mcp-as-a-platform-and-software-factory/</guid>
                    <title>The Agent-Ready CMS: Enable the ecosystem</title>
                    <link>https://umbraco.com/blog/the-agent-ready-cms-enable-the-ecosystem-umbraco-s-mcp-as-a-platform-and-software-factory/</link>
                    <description><![CDATA[Learn how Umbraco&#x2019;s MCP platform and software factory empower partners and clients to build agentic AI tools for a truly agent-ready CMS ecosystem.]]></description>
                    <pubDate>Thu, 02 Jul 2026 00:00:00 Z</pubDate>
                        <category>hq</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.imagesharp.trimcache</guid>
                    <title>Umbraco.Community.ImageSharp.TrimCache</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.imagesharp.trimcache</link>
                    <description><![CDATA[Scheduled, age-based trimming of the ImageSharp.Web image cache for Umbraco. Supports both the Azure Blob cache and the local physical cache, keeping the cache from growing unbounded (for example exceeding Umbraco Cloud media-storage limits). Old variants are removed in the background and regenerated on the next request. Supports Umbraco 13, 17 and 18.]]></description>
                    <pubDate>Thu, 02 Jul 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://www.linkedin.com/feed/update/urn:li:ugcPost:7478382465955500033/</guid>
                    <title>How to setup Claude Design &#x2B; the Umbraco UI Library</title>
                    <link>https://www.linkedin.com/feed/update/urn:li:ugcPost:7478382465955500033/</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Wed, 01 Jul 2026 17:53:35 Z</pubDate>
                        <category>community</category>
                        <category>linkedin</category>
                        <category>social</category>
                </item>
                <item>
                    <guid>https://dev.to/mpisaacs/codegarden-2026-a-little-late-because-it-gave-me-something-to-build-2em6</guid>
                    <title>Codegarden 2026 - a little late, because it gave me something to build</title>
                    <link>https://dev.to/mpisaacs/codegarden-2026-a-little-late-because-it-gave-me-something-to-build-2em6</link>
                    <description><![CDATA[&lt;p&gt;A few weeks ago I was in Copenhagen for my first Codegarden, and one quiet thought has stuck with me since. It didn&#x27;t come from a keynote. It came from the bit the keynote leaves out.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I&#x27;ve worked with Umbraco for years, but I&#x27;d never been to Codegarden, and I turned up without much of a fixed idea of what the two days would be. I kept that open on purpose. I wanted to take it in rather than measure it against something I&#x27;d decided in advance. What struck me most was that the value came from two places at once. The sessions were a fantastic source of inspiration; everything from keynotes to guest speakers all seemed to resonate in some way or another. The conversations in between the sessions - drifting around the event space and finding common ground with anyone and everyone - proved just as valuable. I came home more energised than I&#x27;ve been in a while, with a notebook full of half-formed ideas and a better feel for the community I&#x27;m part of.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;But the thing I kept turning over afterwards was that bit the keynote leaves out. That&#x27;s what I want to write about.&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  The easy half and the hard half&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Every major Umbraco release gets the same treatment. A polished keynote, a clean demo, a feature that looks effortless on stage. There&#x27;s plenty in 18, and which part matters most depends on what you&#x27;re building. For me it&#x27;s Elements: a new Library section where you manage reusable content and reference it through a new element picker. Create once, use everywhere. It&#x27;s a genuinely good direction. Reusable content has lived awkwardly in the content tree for years, and Library finally gives it a proper home.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;What the demos don&#x27;t show you is the part I&#x27;ve been playing around with for the past few weeks. Taking a real Umbraco 17 site, with content pickers threaded through block lists, block grids, rich text blocks and base document properties, and getting all of it to point at the new Library without an editor ever noticing anything moved underneath them.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The feature is the easy half. The migration is the half that decides whether anyone actually uses it.&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  Why migration is where adoption lives&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;A new way of modelling content only matters if existing sites can get to it. New projects will use Library because it&#x27;s there and it&#x27;s the obvious choice. The much bigger pile of work is the sites already in production, built the old way, where reusable content was faked with content pickers pointing at hidden nodes because that was the best tool on offer at the time.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Upgrade conversations with clients are increasingly turning into &quot;end of life is on the way, you need to upgrade!&quot; but Umbraco have given us some genuinely useful new features that can turn those conversations from scaring clients away from security woes to improving their content management and supercharging their marketing activities.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;There&#x27;s a timing thing here. The migration path has to exist when the feature does, not three months later when the upgrade conversation has gone cold. A site that wants Library is at its most willing in the window right after release, while the appetite is fresh and the project is being planned anyway. Miss that window and you&#x27;re asking someone to reopen a decision they&#x27;ve already made, which almost never happens.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;That&#x27;s the question I bring to every shiny thing on a keynote slide. Not &quot;is this exciting&quot;, but &quot;what&#x27;s the real path from a live production site to it, and how much of that path can be made painless&quot;. The exciting idea is the easy part. The route onto it is the work.&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  What the package actually does&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;This is the problem the Library Migrator package is built to solve, and the job is less glamorous than it sounds. It moves documents from Content into Library, so the things that were always meant to be reusable end up where they belong. It swaps every content picker on the relevant types for an element picker pointed at Library, so editors keep the same workflow and have nothing new to learn. And it rewrites the stored values, which is the part that earns its keep: every value held in an old content picker is updated to reference the new elements, across block lists, block grids, rich text blocks and base document properties. One reference left behind is a broken link an editor finds at the worst possible moment.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;None of that shows up in a demo, using a brand new, tailored project designed to show the feature off at its best. Yet content is the centrepiece of all CMS solutions and the value in existing content is always at the forefront of our clients&#x27; minds. Whether it&#x27;s a same-platform upgrade or a complete rebuild, the question of migration always gets raised.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The Library Migrator is out now. If you&#x27;re looking at an Umbraco 17 site and wondering how on earth it&#x27;s going to reach 18&#x27;s (or 21 if you&#x27;re LTS-conscious) Library, that&#x27;s exactly what it&#x27;s for.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&quot;https://marketplace.umbraco.com/package/growcreate.librarymigrator&quot; rel=&quot;noopener noreferrer&quot;&gt;Library Migrator on Umbraco Marketplace&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&quot;https://github.com/GrowCreate/Growcreate.LibraryMigrator&quot; rel=&quot;noopener noreferrer&quot;&gt;Library Migrator repository&lt;/a&gt;&lt;/p&gt;]]></description>
                    <pubDate>Wed, 01 Jul 2026 15:53:03 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://www.dot-see.com/blog/mega-update-dotseediscipline-ui-based-configuration/</guid>
                    <title>Mega update: DotSee.Discipline UI-based configuration</title>
                    <link>https://www.dot-see.com/blog/mega-update-dotseediscipline-ui-based-configuration/</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Wed, 01 Jul 2026 14:26:05 Z</pubDate>
                        <category>blog</category>
                        <category>community</category>
                </item>
                <item>
                    <guid>https://github.com/limbo-works/Limbo.Umbraco.TwentyThree/releases/tag/v17.0.0-alpha001</guid>
                    <title>Limbo.Umbraco.TwentyThree 17.0.0-alpha001</title>
                    <link>https://github.com/limbo-works/Limbo.Umbraco.TwentyThree/releases/tag/v17.0.0-alpha001</link>
                    <description><![CDATA[Video picker for inserting TwentyThree videos in Umbraco.]]></description>
                    <pubDate>Wed, 01 Jul 2026 11:21:15 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                </item>
                <item>
                    <guid>https://www.cantarus.com/articles/codegarden-2026-open-composable-ai-future/?utm_source=linkedin.com&amp;utm_medium=social&amp;utm_campaign=blog-codegarden-2026-06</guid>
                    <title>Umbraco Codegarden 2026: Open, composable and ready for an AI future</title>
                    <link>https://www.cantarus.com/articles/codegarden-2026-open-composable-ai-future/?utm_source=linkedin.com&amp;utm_medium=social&amp;utm_campaign=blog-codegarden-2026-06</link>
                    <description><![CDATA[Cantarus - Umbraco Codegarden 2026: Open, composable and ready for an AI future | Cantarus]]></description>
                    <pubDate>Wed, 01 Jul 2026 08:59:55 Z</pubDate>
                        <category>blog</category>
                        <category>community</category>
                </item>
                <item>
                    <guid>https://kjac.dev/posts/postgresql-provider-for-umbraco-search/</guid>
                    <title>PostgreSQL provider for Umbraco Search</title>
                    <link>https://kjac.dev/posts/postgresql-provider-for-umbraco-search/</link>
                    <description><![CDATA[Introducing a PostgreSQL powered search provider for Umbraco Search.]]></description>
                    <pubDate>Wed, 01 Jul 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/utpro.feature.simpleformbuilder</guid>
                    <title>uTPro.Feature.SimpleFormBuilder</title>
                    <link>https://marketplace.umbraco.com/package/utpro.feature.simpleformbuilder</link>
                    <description><![CDATA[Lightweight form builder for Umbraco 16, 17 and 18 backoffice. Create, manage, and render dynamic forms with 19&#x2B; field types, groups/columns layout, client-side validation, sensitive data encryption, multi-language support, custom field extensibility, entry storage, secure file uploads (stored outside wwwroot, authenticated download), entry export as CSV or ZIP (data &#x2B; uploaded files), and public submit/render APIs. Render any form with a single ViewComponent call. Database-agnostic: runs on SQL Server, SQLite and PostgreSQL.]]></description>
                    <pubDate>Wed, 01 Jul 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/growcreate.librarymigrator</guid>
                    <title>Growcreate.LibraryMigrator</title>
                    <link>https://marketplace.umbraco.com/package/growcreate.librarymigrator</link>
                    <description><![CDATA[A backoffice package for Umbraco 18&#x2B; that migrates content saved as Element Types to the new Library (reusable elements) feature introduced in Umbraco 18.]]></description>
                    <pubDate>Wed, 01 Jul 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/casko.xmlsitemapsforumbraco</guid>
                    <title>Casko.XmlSitemapsForUmbraco</title>
                    <link>https://marketplace.umbraco.com/package/casko.xmlsitemapsforumbraco</link>
                    <description><![CDATA[XML Sitemaps for Umbraco helps Umbraco projects publish XML sitemaps in a structured, configurable way. It is designed for teams that want reliable sitemap delivery for search engines without having to build and maintain the full solution themselves.]]></description>
                    <pubDate>Wed, 01 Jul 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://owain.codes/blog/2026/july/using-umbracoautomate-to-populate-content-from-an-api/</guid>
                    <title>Using Umbraco.Automate to populate content from an API</title>
                    <link>https://owain.codes/blog/2026/july/using-umbracoautomate-to-populate-content-from-an-api/</link>
                    <description><![CDATA[Learn how to automatically populate Umbraco content from an external API using Umbraco.Automate, with a hands-on Pok&#xE9;API example and video demo.]]></description>
                    <pubDate>Wed, 01 Jul 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>http://www.zpqrtbnk.net/posts/u17/</guid>
                    <title>U17</title>
                    <link>http://www.zpqrtbnk.net/posts/u17/</link>
                    <description><![CDATA[&lt;p&gt;This site has started as an Umbraco v4.x site, and has been regularly upgraded since then, never completely rebuilt. It has been running Umbraco 13 for about 3 years now, and it is about time to upgrade to Umbraco 17.&lt;/p&gt;&#xA;&lt;h4&gt;Packages&lt;/h4&gt;&#xA;&lt;p&gt;This is the easy part. The solution contains two projects: a Core project, and a UI project. Open each &lt;code&gt;.csproj&lt;/code&gt; file, bump &lt;code&gt;TargetFramework&lt;/code&gt; from &lt;code&gt;net8.0&lt;/code&gt; to &lt;code&gt;net10.0&lt;/code&gt;, bump Umbraco package references from &lt;code&gt;13.0.2&lt;/code&gt; to &lt;code&gt;17.4.0&lt;/code&gt;, bump a few other packages as per NuGet&#x27;s suggestions.&lt;/p&gt;&#xA;&lt;p&gt;The excellent &lt;a href=&quot;https://docs.umbraco.com/umbraco-cms/get-started/upgrading-and-migrating/version-specific&quot;&gt;Breaking Changes&lt;/a&gt; documentation tells us to remove &lt;code&gt;RazorCompileOnBuild&lt;/code&gt; and &lt;code&gt;RazorCompileOnPublish&lt;/code&gt; so, let us do it. It also tells us to clean our &lt;code&gt;Program&lt;/code&gt; class a little. Remove a &lt;code&gt;.AddDeliveryApi()&lt;/code&gt; call, remove a &lt;code&gt;.UserInstallerEndpoints()&lt;/code&gt; calls, that is it.&lt;/p&gt;&#xA;&lt;p&gt;At this point, rebuilding fails.&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;ModelsBuilderSettings.ModelsMode&lt;/code&gt; used to be an &lt;code&gt;enum&lt;/code&gt;, looks like it is now a &lt;code&gt;string&lt;/code&gt;. Quite simple to fix. Everything that queried the &lt;code&gt;IPublishedContentCache&lt;/code&gt; does not compile anymore, porting to &lt;code&gt;IPublishedContentQuery&lt;/code&gt; is trivial. There is no &lt;code&gt;IContentService.SaveAndPublish()&lt;/code&gt; anymore, apparently, and one needs to &lt;code&gt;Save()&lt;/code&gt; then &lt;code&gt;Publish()&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;All in all, nothing dramatic.&lt;/p&gt;&#xA;&lt;p&gt;Some of my custom Markdown property editor and converter will not compile, I am going to comment them out for the time being.&lt;/p&gt;&#xA;&lt;p&gt;And... it builds.&lt;/p&gt;&#xA;&lt;h4&gt;Database&lt;/h4&gt;&#xA;&lt;p&gt;Trying to boot the site fails... with a &lt;code&gt;BootFailedException&lt;/code&gt;. A migration seems to want to delete a non-existing constraint named &lt;code&gt;DF_umbracoUser_createDate&lt;/code&gt;. A quick Internet search shows that this happened to others as well, so something must have gone wrong with migrations at some point. Not going to troubleshoot, creating the missing constraints before upgrading is quicker:&lt;/p&gt;&#xA;&lt;pre class=&quot;prettyprint&quot;&gt;&lt;code&gt; ALTER TABLE umbracoUser ADD CONSTRAINT DF_umbracoUser_createDate DEFAULT GETUTCDATE() FOR createDate;&#xA; ALTER TABLE umbracoUser ADD CONSTRAINT DF_umbracoUser_updateDate  DEFAULT GETUTCDATE() FOR updateDate;&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And presto... the site upgrades, boots, and I can log into the back-office.&lt;/p&gt;&#xA;&lt;h4&gt;Data Types&lt;/h4&gt;&#xA;&lt;p&gt;A range of data types are gone or have changed. And of course my custom data types are CompletelyBroken&#x2122; which is not a surprise, since the back-office UI has been entirely rebuilt.&lt;/p&gt;&#xA;&lt;p&gt;First, native data types. Basically, go into the &lt;em&gt;Data Types&lt;/em&gt; back-office section, and re-assign those that have issues to the proper property type. Rather simple. Weird enough, a content list datatype is throwing in the back-office, because of its &lt;code&gt;orderBy&lt;/code&gt; value. Something a migration did not catch? Manually re-saving the datatype fixes it.&lt;/p&gt;&#xA;&lt;p&gt;And then, I actually use two custom data types:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;code&gt;ZpqrtBnk.ImgFocus&lt;/code&gt; is an image focus data type which is an alternative to crops. It allows the user to define a rectangle that represents the &amp;quot;zone of interest&amp;quot; of an image. That zone is defined on the media itself. Next, whenever we need to render the media, we can automatically figure out the best crop based upon this zone.&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;ZpqrtBnk.Markdown&lt;/code&gt; is a custom Markdown data type that uses the back-office widget pretty much unchanged, but implements some rendering helpers for links or images.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;As far as Markdown is concerned, I was using a property editor in order to support additional custom syntax. Turns out a property editor is not needed anymore, a plain &lt;code&gt;IMarkdownToHtmlConverter&lt;/code&gt; implementation is all that is needed. So, the property editor is gone, and it is way nicer this way.&lt;/p&gt;&#xA;&lt;p&gt;On the other hand the image focus editor needs to be completely rebuilt.&lt;/p&gt;&#xA;&lt;h4&gt;My First Property Editor&lt;/h4&gt;&#xA;&lt;p&gt;There is some nice &lt;a href=&quot;https://docs.umbraco.com/umbraco-cms/extend-your-project/tutorials/creating-a-property-editor&quot;&gt;documentation&lt;/a&gt; about property editors in v17, so let us follow it.&lt;/p&gt;&#xA;&lt;pre class=&quot;prettyprint&quot;&gt;&lt;code&gt;mkdir PropertyEditors&#xA;cd PropertyEditors&#xA;npm create vite@latest ZpqrtBnk.ImgFocus&#xA;# with Lit&#xA;# with TypeScript&#xA;# without Vite RollDown (but I was not proposed it)&#xA;cd ZpqrtBnk.ImgFocus&#xA;npm i &amp;amp;&amp;amp; npm install -D @umbraco-cms/backoffice@17.4.0&#xA;rm -rf public/* src/*&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Then,&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Update &lt;code&gt;vite.config.ts&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;Create &lt;code&gt;src/zpqrtbnk-imgfocus.element.ts&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;Create &lt;code&gt;public/umbraco-package.json&lt;/code&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Is all it takes. OK, it takes a bit of time to figure out how to put everything together but hey, this is my very first time with the new UI. The end result is &lt;em&gt;quite&lt;/em&gt; polished. As in, it makes way more sense than the convoluted Angular version.&lt;/p&gt;&#xA;&lt;p&gt;In the end,&lt;/p&gt;&#xA;&lt;pre class=&quot;prettyprint&quot;&gt;&lt;code&gt;npm run build&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Drops files in my site&#x27;s &lt;code&gt;App_Plugins&lt;/code&gt; and we are done. As in, it just works. I have to say the experience is quite pleasant.&lt;/p&gt;&#xA;&lt;h4&gt;Models&lt;/h4&gt;&#xA;&lt;p&gt;We are not entirely done with backend work. A few more things have changed, including the CLR type of objects returned by various data types.&lt;/p&gt;&#xA;&lt;p&gt;The new &lt;code&gt;MediaPicker3&lt;/code&gt; for instance does not return a plain &lt;code&gt;IPublishedContent&lt;/code&gt;, but a &lt;code&gt;MediaWithCrops&lt;/code&gt;. I do not care about crops. And I had a media converter ensuring that the property value type would be reported as &lt;code&gt;Image&lt;/code&gt; in case the picker can only pick one single image. So... that converter needs a bit of update to report the proper type, and to unwrap &lt;code&gt;MediaWithCrops&lt;/code&gt; to &lt;code&gt;Image&lt;/code&gt; wherever appropriate.&lt;/p&gt;&#xA;&lt;p&gt;And then, with the various changes applied to property types, I though I would rebuild my models. Turns out they were built using the &lt;code&gt;Our.ModelsBuilder&lt;/code&gt; edition of the Models Builder, not the built-in one, because I am using some extra features.&lt;/p&gt;&#xA;&lt;h4&gt;Front-End Time&lt;/h4&gt;&#xA;&lt;p&gt;At this point, I have a running back-office, clean data types (though missing my Markdown converter, but that will be fixed later), everything is nice, time to test the front-end.&lt;/p&gt;&#xA;&lt;p&gt;And... it does not work.&lt;/p&gt;]]></description>
                    <pubDate>Tue, 30 Jun 2026 18:17:02 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://www.youtube.com/watch?v=_tNVDlw2T18</guid>
                    <title>Umbraco Automate demo, Umbraco Codegarden 2026</title>
                    <link>https://www.youtube.com/watch?v=_tNVDlw2T18</link>
                    <description><![CDATA[Discover the capabilities of Umbraco Automate, a native workflow automation tool integrated directly into the Umbraco back office. This session provides a comprehensive look at how you can create, manage, and execute complex automation chains triggered by backend events like content modifications or media uploads.&#xA;&#xA;Learn how the architecture coordinates triggers and actions, allowing you to build intricate logic chains across the entire Umbraco ecosystem. The presentation details native integrations with Umbraco Engage, Forms, Commerce, Deploy, and AI Agents, demonstrating how workflows can operate autonomously when ecosystem events occur.&#xA;&#xA;Who This Video Is For&#xA;This video is designed for Umbraco developers, system architects, and content administrators looking to streamline backend operations. Understanding these automation workflows will help teams eliminate repetitive tasks, integrate external systems seamlessly, and safely embed AI utilities into their daily content management processes.&#xA;&#xA;Chapters&#xA;00:00 - Introduction to Umbraco Automate&#xA;&#xA;00:38 - Understanding Triggers, Actions, and Logic Chains&#xA;&#xA;00:54 - Ecosystem Integration: Forms, Commerce, Deploy, and AI&#xA;&#xA;01:18 - Demo: Content Saved Trigger &amp; Slack Notification Setup&#xA;&#xA;02:34 - Demo: Connecting AI Agents and Webhooks&#xA;&#xA;03:48 - Demo: Automated Media Transcription on Upload&#xA;&#xA;05:26 - Implementing a Human-in-the-Loop Approval Step&#xA;&#xA;06:30 - Community Packages and Early Access Extensions&#xA;&#xA;07:34 - Open Source Availability and Wrap-up&#xA;&#xA;Key Takeaways&#xA;Native Workflow Engine: Build and manage complex automation chains directly within the Umbraco back office without relying on external third-party integration platforms.&#xA;&#xA;AI &amp; Webhook Extensibility: Send data to AI agents for automated summaries or transcriptions, and route outputs to external endpoints via standard HTTP webhooks.&#xA;&#xA;Human-in-the-Loop Guardrails: Insert manual approval gates into automated processes to pause execution until an administrator reviews and verifies the data.&#xA;&#xA;Ecosystem &amp; Community Ready: Supports core Umbraco products alongside popular community packages like Translation Manager for automated translations and Newsletter Studio for transactional mailing lists.&#xA;&#xA;Free and Open Source: Umbraco Automate is fully open source and available for immediate deployment.&#xA;&#xA;Important Links&#xA;Umbraco Automate Project Page: [Insert Link]&#xA;&#xA;Launch Announcement &amp; Documentation: [Insert Link]&#xA;&#xA;Community Extension Guide: [Insert Link]&#xA;&#xA;Featured Session - AI and Umbraco by Matt: [Insert Link]]]></description>
                    <pubDate>Tue, 30 Jun 2026 08:41:04 Z</pubDate>
                        <category>hq</category>
                        <category>youtube</category>
                </item>
                <item>
                    <guid>https://skttl.dev/blog/small-ux-details-ai-coding/</guid>
                    <title>Small UX Details Make AI Coding Better</title>
                    <link>https://skttl.dev/blog/small-ux-details-ai-coding/</link>
                    <description><![CDATA[After trying Devin, Windsurf, Codeium, Claude Code, and now the Codex desktop app, I keep coming back to the same thing: small interface details matter a lot when AI is writing code.]]></description>
                    <pubDate>Tue, 30 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/phases.umbraco.community.templatehistory</guid>
                    <title>Phases.Umbraco.Community.TemplateHistory</title>
                    <link>https://marketplace.umbraco.com/package/phases.umbraco.community.templatehistory</link>
                    <description><![CDATA[Track version history for Umbraco templates, stylesheets, scripts, and partial views. Compare diffs side-by-side or unified, restore previous versions, and browse recent changes from a dedicated History workspace tab and Settings dashboard.]]></description>
                    <pubDate>Tue, 30 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/oc.automate.linkedin</guid>
                    <title>OC.Automate.LinkedIn</title>
                    <link>https://marketplace.umbraco.com/package/oc.automate.linkedin</link>
                    <description><![CDATA[LinkedIn integration for Umbraco Automate. Post content to LinkedIn as part of your automation workflows.]]></description>
                    <pubDate>Tue, 30 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/knowit.umbraco.aitranslate</guid>
                    <title>Knowit.Umbraco.AiTranslate</title>
                    <link>https://marketplace.umbraco.com/package/knowit.umbraco.aitranslate</link>
                    <description><![CDATA[A guided AI translation dashboard for Umbraco. Pick a language pair (or create a new language), choose pages or the whole site, and translate content into other languages using your Umbraco.AI profile. Media references are carried over, link titles are translated, and everything is saved as drafts for review. Requires the Umbraco.AI package.]]></description>
                    <pubDate>Tue, 30 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umcontenttranslator</guid>
                    <title>umContentTranslator</title>
                    <link>https://marketplace.umbraco.com/package/umcontenttranslator</link>
                    <description><![CDATA[Translate Umbraco content across cultures with AI. umContentTranslator walks your content tree, collects translatable values, batches them, and writes the AI translations back into the target languages &#x2014; preserving Block Grid and Block List structure, rich text, Markdown, links, and other editor-specific data. Powered by Claude (Anthropic) or OpenAI, it also translates Umbraco dictionary items and adds a Content Translator section with a translation dialog and a Translation Logs dashboard. Includes a built-in free trial.]]></description>
                    <pubDate>Tue, 30 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://umbraco.com/blog/going-from-umbraco-13-to-17/</guid>
                    <title>Going from Umbraco 13 to 17</title>
                    <link>https://umbraco.com/blog/going-from-umbraco-13-to-17/</link>
                    <description><![CDATA[Upgrading from Umbraco 13 to 17 LTS? Discover the two main migration paths and learn how Umbraco Cloud can smooth your transition before the 2026 EOL date for Umbraco 13.]]></description>
                    <pubDate>Tue, 30 Jun 2026 00:00:00 Z</pubDate>
                        <category>hq</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://dev.to/luukpeters/advanced-permissions-meets-umbraco-18-26g0</guid>
                    <title>Advanced Permissions meets Umbraco 18!</title>
                    <link>https://dev.to/luukpeters/advanced-permissions-meets-umbraco-18-26g0</link>
                    <description><![CDATA[&lt;p&gt;A few days ago, the final version of &lt;a href=&quot;https://umbraco.com/blog/umbraco-18-release/&quot; rel=&quot;noopener noreferrer&quot;&gt;Umbraco 18 was released&lt;/a&gt;! So it was time to update my Advanced Permissions package to support Umbraco 18.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;This was not just a simple case of updating a few namespaces and dependencies and calling it done. The main new feature in Umbraco 18 was a perfect candidate for Advanced Permissions support, so that is exactly what I added!&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  What is new in Umbraco 18&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;The Umbraco 18 release is (and I quote) &quot;a short and sweet release&quot;. The main attraction is the new Library section and the first version of reusable Elements.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&quot;https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffkf4v757xyftp3s0ci5m.png&quot; class=&quot;article-body-image-wrapper&quot;&gt;&lt;img src=&quot;https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffkf4v757xyftp3s0ci5m.png&quot; alt=&quot;The new Library section in Umbraco 18&quot; width=&quot;771&quot; height=&quot;366&quot;&gt;&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Reusable Elements in the Library section are essentially Content nodes without rendering and routing. Other than that, they behave a lot like Content: you can create, delete, move them, and so on. That made them the perfect candidate for support in v18 of the Advanced Permissions package.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Besides Library support, the package also has a few other improvements and additions. Let&#x27;s talk about them!&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  Library support!&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;The first obvious new feature is the Permissions Editor for the Library. Just like with Content, you can set permissions for a User Group using the same inheritance and scoping system as the Content Permissions Editor.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&quot;https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8nndmdxhifxli40asm5w.png&quot; class=&quot;article-body-image-wrapper&quot;&gt;&lt;img src=&quot;https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8nndmdxhifxli40asm5w.png&quot; alt=&quot;The Library Permissions Editor&quot; width=&quot;800&quot; height=&quot;313&quot;&gt;&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;You&#x27;ll notice that not every permission is applicable in every case, so N/A is displayed when a permission does not apply.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;And just like with Content, the Library also has an Access Viewer where you can see the effective permissions for a User Group or an individual User.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&quot;https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzbiitpigy6g93hfw3092.png&quot; class=&quot;article-body-image-wrapper&quot;&gt;&lt;img src=&quot;https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzbiitpigy6g93hfw3092.png&quot; alt=&quot;The Library Access Viewer&quot; width=&quot;800&quot; height=&quot;287&quot;&gt;&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I also added a Library Element Type Permissions Editor. Just like the Document Type Permissions Editor, you can set the insert options for Element Types for a specific User Group.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&quot;https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ft64dxrjo4kahxha0w8j7.png&quot; class=&quot;article-body-image-wrapper&quot;&gt;&lt;img src=&quot;https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ft64dxrjo4kahxha0w8j7.png&quot; alt=&quot;The Library Element Type Permissions Editor&quot; width=&quot;800&quot; height=&quot;265&quot;&gt;&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;With this Permissions Editor, you can control whether a User Group can create instances of an Element Type. This acts as a filter on the &quot;create&quot; list in the Library. And when a User has multiple User Groups, the well-established resolver will determine the effective permissions.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Currently, because of a limitation in Umbraco, it is not yet possible to scope these permissions to a specific part of the Library tree like the Document Type Permissions Editor does.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;And of course, the Element Type Permissions Editor also has an associated Access Viewer.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&quot;https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Febygmk78o91jrk6chea0.png&quot; class=&quot;article-body-image-wrapper&quot;&gt;&lt;img src=&quot;https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Febygmk78o91jrk6chea0.png&quot; alt=&quot;Library Elements Access Viewer&quot; width=&quot;800&quot; height=&quot;270&quot;&gt;&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  Redesign&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Because of all these new Permissions Editors and Access Viewers, the menu became harder to read at a glance. So the main menu has been redesigned around the scope of the editor and viewer.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&quot;https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1g4dv1ag1ofbm6hh95uw.png&quot; class=&quot;article-body-image-wrapper&quot;&gt;&lt;img src=&quot;https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1g4dv1ag1ofbm6hh95uw.png&quot; alt=&quot;The reworked menu of Advanced Permissions&quot; width=&quot;800&quot; height=&quot;390&quot;&gt;&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;All editors and viewers in the menu are now called Permissions Editor and Access Viewer respectively. Their purpose is determined by the menu header they are under: Content, Document Type, Library, or Library Element Type.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;In the screenshot, you&#x27;ll also notice a slight redesign of the workspaces for the editors and viewers. They now look more Umbraco native and display a one-line description of what the editor or viewer is for. And when you have not selected anything yet, it will now display a much nicer view. This will also be ported back to the Umbraco 17 version.&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  To help or not to help&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;In the top-right corner of each editor or viewer, you&#x27;ll also notice a &quot;learn more&quot; button. This button gives access to more detailed documentation. It describes what the editor or viewer is for, and it links to more generic documentation explaining the concepts.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Consider this a first version. It is already much better than nothing, but I think it can still be improved over time. This will also be ported back to the Umbraco 17 version.&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  Localization support!&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;And lastly, apart from the expanded documentation, Advanced Permissions now has localization for all languages that the Backoffice supports. Obviously, these translations are automatically generated because I am not fluent in 28 languages, so if you find an error, please let me know!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;All in all, I think this is a very nice and complete release. I&#x27;m happy that Advanced Permissions can support new Umbraco features as soon as they come out.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;You can find Advanced Permissions for Umbraco here:&lt;/p&gt;&#xA;&#xA;&lt;p&gt;NuGet:&lt;br&gt;&#xA;&lt;a href=&quot;https://www.nuget.org/packages/Umbraco.Community.AdvancedPermissions/&quot; rel=&quot;noopener noreferrer&quot;&gt;https://www.nuget.org/packages/Umbraco.Community.AdvancedPermissions/&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The Umbraco Marketplace:&lt;br&gt;&#xA;&lt;a href=&quot;https://marketplace.umbraco.com/package/umbraco.community.advancedpermissions&quot; rel=&quot;noopener noreferrer&quot;&gt;https://marketplace.umbraco.com/package/umbraco.community.advancedpermissions&lt;/a&gt;&lt;/p&gt;]]></description>
                    <pubDate>Sun, 28 Jun 2026 19:49:52 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://owain.codes/blog/2026/june/ocautomatelinkedin-now-available/</guid>
                    <title>OC.Automate update</title>
                    <link>https://owain.codes/blog/2026/june/ocautomatelinkedin-now-available/</link>
                    <description><![CDATA[OC.Automate.LinkedIn is out of beta and OC.Automate.Bluesky and OC.Automate.Mastodon are all working on Umbraco 18]]></description>
                    <pubDate>Sun, 28 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://www.youtube.com/watch?v=mEa90pJb0Bw</guid>
                    <title>umbraCoffee - Codegarden 2026 Wrapped &#x1F32F;</title>
                    <link>https://www.youtube.com/watch?v=mEa90pJb0Bw</link>
                    <description><![CDATA[Welcome to your monthly dose of #umbraCoffee&#x200B;&#x200B;&#x200B;&#x200B;&#x200B;&#x200B;&#x200B;&#x200B;&#x200B;&#x200B;&#x200B;&#x200B;! Your hosts - Marcin and Callum - together with their guest(s) will drive through all of the community news and happenings in the Umbraco world. So... grab a cuppa, join us LIVE and enjoy!&#xA;&#xA;See ya?!&#xA;&#xA;---&#xA;&#x2615; Wanna buy us a coffee/pizza/donuts?&#xA;https://www.buymeacoffee.com/umbracoffee&#xA;---&#xA;&#xA;Topics:&#xA;//ToDo:]]></description>
                    <pubDate>Fri, 26 Jun 2026 23:06:54 Z</pubDate>
                        <category>community</category>
                        <category>youtube</category>
                </item>
                <item>
                    <guid>https://github.com/umbraco/Announcements/issues/36</guid>
                    <title>[Breaking change]: Umbraco Search replaces existing search in Umbraco 19</title>
                    <link>https://github.com/umbraco/Announcements/issues/36</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Fri, 26 Jun 2026 11:38:19 Z</pubDate>
                        <category>hq</category>
                        <category>announcement</category>
                </item>
                <item>
                    <guid>https://community.umbraco.com/blog/2026/06/what-were-most-excited-about-on-the-new-community-site-part-1-of-2/</guid>
                    <title>What we&#x27;re most excited about on the new Community site - part 1 of 2</title>
                    <link>https://community.umbraco.com/blog/2026/06/what-were-most-excited-about-on-the-new-community-site-part-1-of-2/</link>
                    <description><![CDATA[What we&#x27;re most excited about on the new Community site - part 1 of 2 | Umbraco Community]]></description>
                    <pubDate>Fri, 26 Jun 2026 11:16:40 Z</pubDate>
                        <category>blog</category>
                        <category>community</category>
                </item>
                <item>
                    <guid>https://anju-dev-notes.hashnode.dev/my-first-codegarden-experience-a-journey-from-india-to-copenhagen</guid>
                    <title>My First Codegarden Experience &#x2014; A Journey from India to Copenhagen</title>
                    <link>https://anju-dev-notes.hashnode.dev/my-first-codegarden-experience-a-journey-from-india-to-copenhagen</link>
                    <description><![CDATA[Attending Codegarden for the first time was truly a milestone moment in my career &#x2014; not just because of the event itself, but because it also became a very personal and memorable journey for me.&#xA;This]]></description>
                    <pubDate>Fri, 26 Jun 2026 10:36:14 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://github.com/limbo-works/Limbo.Umbraco.Innomate/releases/tag/v13.0.0-alpha004</guid>
                    <title>Limbo.Umbraco.Innomate 13.0.0-alpha004</title>
                    <link>https://github.com/limbo-works/Limbo.Umbraco.Innomate/releases/tag/v13.0.0-alpha004</link>
                    <description><![CDATA[Umbraco integration for the Innomate API.]]></description>
                    <pubDate>Fri, 26 Jun 2026 09:02:31 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.entityactions.forcedelete</guid>
                    <title>Umbraco.Community.EntityActions.ForceDelete</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.entityactions.forcedelete</link>
                    <description><![CDATA[Add a Force Delete entity action to the Umbraco backoffice, allowing developers and editors to permanently remove documents.]]></description>
                    <pubDate>Fri, 26 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.schemeweaver.ai</guid>
                    <title>Umbraco.Community.SchemeWeaver.AI</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.schemeweaver.ai</link>
                    <description><![CDATA[AI-powered schema mapping for SchemeWeaver using Umbraco.AI]]></description>
                    <pubDate>Fri, 26 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://owain.codes/blog/2026/june/umbraco-automate/</guid>
                    <title>Umbraco Automate</title>
                    <link>https://owain.codes/blog/2026/june/umbraco-automate/</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Fri, 26 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://owain.codes/blog/2026/june/umbraco-automate-workflows/</guid>
                    <title>Umbraco Automate Workflows</title>
                    <link>https://owain.codes/blog/2026/june/umbraco-automate-workflows/</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Fri, 26 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://www.proworks.com/blog/archive/building-with-claude-and-umbraco-setting-up-mcp-and-creating-content-with-ai/</guid>
                    <title>Building with Claude and Umbraco: Setting Up MCP and Creating Content with AI</title>
                    <link>https://www.proworks.com/blog/archive/building-with-claude-and-umbraco-setting-up-mcp-and-creating-content-with-ai/</link>
                    <description><![CDATA[&lt;p&gt;I&#x27;ll be honest, when Jason first mentioned setting up an MCP server to connect Claude to our Umbraco dev environment, I assumed it was going to be a difficult dev-heavy project that would take the day at least, and be a bit past my coding comprehension ability as a Front End Developer. I even made a new local branch assuming I was going to have to write and commit code.&lt;/p&gt;&#xA;&lt;p&gt;Nope! It wasn&#x27;t like that at all. And I&#x27;m still a little surprised about it. It was just setting up a config file in Claude and setting up API users in Umbraco.&lt;/p&gt;&#xA;&lt;p&gt;If you&#x27;re an Umbraco developer who&#x27;s been curious about AI-assisted content workflows but figured the setup overhead wasn&#x27;t worth it, this post is for you. I&#x27;m going to walk through exactly what I did, what tripped me up (spoiler: one small thing), and what became possible on the other side of it.&lt;/p&gt;&#xA;&lt;hr /&gt;&#xA;&lt;h2&gt;Part 1: What Is the Umbraco MCP Server, Anyway?&lt;/h2&gt;&#xA;&lt;p&gt;MCP stands for Model Context Protocol. It&#x27;s an open standard that lets AI assistants like Claude connect directly to external tools and services, not just chat about them, but actually interact with them.&lt;/p&gt;&#xA;&lt;p&gt;The &lt;a href=&quot;https://docs.umbraco.com/umbraco-in-ai/mcp/cms-developer-mcp&quot;&gt;Umbraco MCP server&lt;/a&gt; is an implementation of that standard for Umbraco. Once it&#x27;s set up and connected, Claude can read and write content in your Umbraco instance through the Management API. We&#x27;re talking creating pages, updating properties, working with block components, the same things you&#x27;d do in the back office, but driven by Claude. It&#x27;s actually pretty amazing to see it work.&lt;/p&gt;&#xA;&lt;hr /&gt;&#xA;&lt;h2&gt;Part 2: Setting Up the MCP Server&lt;/h2&gt;&#xA;&lt;p&gt;Before anything else, a quick note on prerequisites. You&#x27;ll need an Umbraco site to connect to (we&#x27;re using our dev environment), and Claude Desktop or Cowork installed on your machine. That&#x27;s really it on the &amp;quot;before you start&amp;quot; front, which was the first pleasant surprise.&lt;/p&gt;&#xA;&lt;p&gt;The MCP server itself is configured through a JSON config file in Claude. Go to your &lt;strong&gt;Claude settings&lt;/strong&gt;, then &lt;strong&gt;Developer&lt;/strong&gt;, and click the &lt;strong&gt;&amp;quot;Edit Config&amp;quot;&lt;/strong&gt; button to bring up the &lt;em&gt;&lt;strong&gt;claude_desktop_config.json&lt;/strong&gt;&lt;/em&gt; file in your favorite editor.&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Close Claude completely (including killing it in the taskbar) while working on the config file. If Claude is running, it will overwrite your changes when it closes.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Make sure you&#x27;re on the latest version of Node before you start.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;Drop this into your config file, change the name as you like, change the BASE_URL to your site, and we&#x27;ll cover the CLIENT_ID and SECRET in the next steps.&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code class=&quot;language-json&quot;&gt;&amp;quot;mcpServers&amp;quot;: {&#xA;  &amp;quot;YOUR-umbraco-dev-mcp-server&amp;quot;: {&#xA;    &amp;quot;command&amp;quot;: &amp;quot;npx&amp;quot;,&#xA;    &amp;quot;args&amp;quot;: [&#xA;      &amp;quot;@umbraco-cms/mcp-dev@latest&amp;quot;&#xA;    ],&#xA;    &amp;quot;env&amp;quot;: {&#xA;      &amp;quot;UMBRACO_CLIENT_ID&amp;quot;: &amp;quot;umbraco-back-office-api-user&amp;quot;,&#xA;      &amp;quot;UMBRACO_CLIENT_SECRET&amp;quot;: &amp;quot;12345-GUID-OR-PASSWORD-6789&amp;quot;,&#xA;      &amp;quot;UMBRACO_BASE_URL&amp;quot;: &amp;quot;https://your-site.io&amp;quot;,&#xA;      &amp;quot;UMBRACO_INCLUDE_TOOL_COLLECTIONS&amp;quot;: &amp;quot;document,media,document-type,data-type&amp;quot;&#xA;    }&#xA;  }&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;hr /&gt;&#xA;&lt;h2&gt;Part 3: Creating an API User in the Umbraco Back Office&lt;/h2&gt;&#xA;&lt;p&gt;This is the part I was most nervous about. &amp;quot;API user&amp;quot; sounds like something that involves a terminal and a lot of Googling. It does not. It&#x27;s just a few clicks in the Umbraco back office and I was genuinely a little embarrassed by how straightforward it was.&lt;/p&gt;&#xA;&lt;p&gt;Head into your Umbraco back office and navigate to the Users section. We&#x27;re going to create both a new User Group and a new API user. First, the User Group. Create one and call it MCP-User-Developer and give it as much control as a developer would. If you ever wanted another group called MCP-User-Editor with less control, you can do that too. For now, add Content, Media and Settings sections and turn on everything you&#x27;d like it to have access to.&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&quot;https://dev-proworks-v13-site.useast01.umbraco.io/media/5sbd1xfk/group-1.png&quot; alt=&quot;creating a user group&quot; /&gt;&lt;/p&gt;&#xA;&lt;p&gt;Next, go to Users and create a new API User. Name it something like &amp;quot;something-mcp-developer&amp;quot; and make it a member of the MCP-User-Developer group we just made. Add an email address for its username and check on access to start nodes (or give it full access).&lt;/p&gt;&#xA;&lt;p&gt;Now the key step: click the Client Credentials button to add the key we&#x27;ll need in the Claude config file. The ID will have a prefix of &amp;quot;umbraco-back-office&amp;quot; and then you name it whatever you want. In my example I went with &amp;quot;api-user&amp;quot;, so the full ID becomes &amp;quot;umbraco-back-office-api-user&amp;quot;. For the Secret, generate a GUID or secure password however you like.&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Once you click Create, the password won&#x27;t be visible again. Save it somewhere before moving on!&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;&lt;img src=&quot;https://dev-proworks-v13-site.useast01.umbraco.io/media/oshpbxuf/credentials.png&quot; alt=&quot;credentials&quot; /&gt;&lt;/p&gt;&#xA;&lt;p&gt;Now we have all the info for the config file. Go back and add &amp;quot;umbraco-back-office-api-user&amp;quot; to the &lt;code&gt;UMBRACO_CLIENT_ID&lt;/code&gt; and your password to the &lt;code&gt;UMBRACO_CLIENT_SECRET&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;hr /&gt;&#xA;&lt;h2&gt;Part 4: Connecting Claude to Your Umbraco Site&lt;/h2&gt;&#xA;&lt;p&gt;At this point you&#x27;ve got the config file set up and your API user created. The last step is getting Claude to actually recognize the connection. Save your claude_desktop_config.json file and restart Claude. Go to Settings, then Developer again, and you should see your MCP server listed there and running.&lt;/p&gt;&#xA;&lt;p&gt;I was stuck here for a bit because I was not on the latest version of Node, and also because I had the UMBRACO_CLIENT_ID wrong. Woops! So make sure your config has all the correct info. But if everything checks out you should see a &amp;quot;running&amp;quot; label next to your server, and you&#x27;re now connected!&lt;/p&gt;&#xA;&lt;p&gt;A quick way to confirm everything is working is to just ask Claude something simple about your site. Something like &amp;quot;list the pages under the home node&amp;quot; or &amp;quot;what document types are available?&amp;quot; If Claude comes back with real data from your Umbraco instance, you&#x27;re in business. As soon as it gave me the ID of the home node of our dev site, I knew things were about to get real.&lt;/p&gt;&#xA;&lt;hr /&gt;&#xA;&lt;h2&gt;Part 5: Creating Content with Claude&lt;/h2&gt;&#xA;&lt;p&gt;This is the fun part.&lt;/p&gt;&#xA;&lt;p&gt;Once Claude is connected to your Umbraco instance, you can start asking it to do real content work. Not just drafting copy in the chat window, but actually creating and populating pages inside Umbraco. I started simple, asking Claude to create a Basic Page under the home node with a title and some body text. It did it. First try. I went and checked the back office and there it was, sitting as a draft, ready to review.&lt;/p&gt;&#xA;&lt;p&gt;From there I started pushing it further. Our Basic Page document type has a bunch of block components available, things like Feature Boxes, Statistics, Testimonials, FAQ sections, Numbered Steps, and a Two-Column Comparison block. I described what I wanted the page to be about and asked Claude to use as many relevant components as made sense for the content. The results were genuinely impressive, well-structured pages with appropriate blocks chosen for the content, not just a wall of rich text.&lt;/p&gt;&#xA;&lt;p&gt;A few tips from what I&#x27;ve learned so far:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;Give Claude context about your document types.&lt;/strong&gt; The more it knows about your block components and what fields they have, the better the output.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Keep pages as drafts first.&lt;/strong&gt; Claude creates content as drafts by default, which is exactly what you want. Review before publishing.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Be specific about tone and content.&lt;/strong&gt; Claude will make reasonable choices on its own, but the more direction you give it, the closer the first draft will be to what you actually want.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Watch out for placeholder content.&lt;/strong&gt; Claude may generate fictional quotes or statistics as placeholders. Always review before anything goes live.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;One small thing to be aware of: on our setup, pages created via the MCP server sometimes needed the template set manually in the back office before they&#x27;d render on the front end. It&#x27;s a quick fix, just one more thing to check on your first run through.&lt;/p&gt;&#xA;&lt;hr /&gt;&#xA;&lt;h2&gt;Part 6: Real-World Use Cases&lt;/h2&gt;&#xA;&lt;p&gt;So what&#x27;s this actually good for in practice? After spending some time with it, here are the use cases that have stood out most.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Spinning up draft pages quickly.&lt;/strong&gt; If you&#x27;ve got a list of pages that need to exist, Claude can create and populate them fast. What might take an editor an afternoon of copying, pasting and formatting can happen in minutes. The drafts still need a human review pass, but you&#x27;re starting from something solid rather than a blank page.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Consistent page structure across a site.&lt;/strong&gt; When Claude is working from the same document type and block components every time, the output is naturally consistent. Every page gets a hero, a logical block order, appropriate use of the available components. It&#x27;s a lot harder to end up with that one orphaned page that&#x27;s formatted completely differently from everything else.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Exploring content strategy.&lt;/strong&gt; This one surprised me. Being able to say &amp;quot;create a page making the case for upgrading Umbraco and use whichever block components make sense&amp;quot; and get back a fully structured draft is genuinely useful for figuring out what you actually want to say. It&#x27;s a fast way to go from a topic to a first draft you can react to.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Auditing and rewriting existing content.&lt;/strong&gt; Claude can read your existing pages too, which means you can ask it to review copy, flag inconsistencies, or suggest rewrites across multiple pages without touching the back office yourself.&lt;/p&gt;&#xA;&lt;p&gt;Like I said, I knew things were about to get real.&lt;/p&gt;&#xA;&lt;p&gt;We&#x27;re still figuring out the best workflows ourselves at ProWorks, but it&#x27;s already changing how we think about content production. I&#x27;m excited to see where it goes from here.&lt;/p&gt;&#xA;&lt;p&gt;If you have questions or want to share what you&#x27;ve built with it, feel free to reach out.&lt;/p&gt;&#xA;&lt;p&gt;&lt;em&gt;Alan Ballard, Front End Developer, ProWorks&lt;/em&gt;&lt;/p&gt;]]></description>
                    <pubDate>Thu, 25 Jun 2026 16:00:16 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://www.youtube.com/watch?v=WtatxMNRW8Y</guid>
                    <title>Umbraco MCP as a Platform Intoduction</title>
                    <link>https://www.youtube.com/watch?v=WtatxMNRW8Y</link>
                    <description><![CDATA[Phil Whittaker and Bolette Kern introduce the &quot;Umbraco in AI&quot; framework, showcasing how the Umbraco Management API exposes content, media, document types, and search configurations to modern AI models. This session highlights how to bridge the CMS with artificial intelligence using the Model Context Protocol (MCP) and dedicated command-line tools.&#xA;&#xA;Learn how to move beyond local environments using Hosted MCP servers with secure OAuth authentication, connect terminal environments directly via the new CLI tool, and use the Base MCP SDK to make custom Umbraco packages agent-ready. The talk also explores advanced architectural patterns like MCP chaining and an automated five-phase Software Factory.&#xA;&#xA;This video is for Umbraco package authors, digital agencies, and platform developers looking for a structured path to implement AI agents. By leveraging these official tools, development teams can eliminate manual integration plumbing and focus entirely on building custom logic, strategy, and creative experiences for clients.&#xA;&#xA;Key Takeaways:&#xA;- Management API Core: Serves as the central translation engine, transforming structured CMS capabilities into discoverable data points that LLMs can read, reason about, and automate.&#xA;&#xA;- Multi-Channel Architecture: Support for Local MCP (on-machine agents), Hosted MCP (cloud remote agent access via secure user authentication), and a developer-centric CLI tool.&#xA;&#xA;- Marketplace Readiness: The official Base MCP SDK enables package authors to instantly convert existing OpenAPI schemas into functional MCP servers with minimal overhead.&#xA;&#xA;- The Five-Phase Software Factory: A command-line toolkit that handles boilerplate scaffolding, project configuration, API schema discovery, tool generation, and automated integration/evaluation testing.&#xA;&#xA;- Advanced MCP Chaining: Eliminates redundant manual configurations through structural orchestration patterns like proxying, delegation, and composite multi-step tools.&#xA;&#xA;Timeline Chapters: &#xA;00:00 - Introduction to the Umbraco in AI Strategy&#xA;00:59 - Interactive Integration Diagram Overview&#xA;01:07 - The Central Role of the Umbraco Management API&#xA;01:29 - Stage 1: The Local Developer MCP Foundation&#xA;02:10 - Stage 2: Hosted MCP and Custom ChatGPT App Setup Demo&#xA;03:24 - Native Connections via the CLI Tool and Claude Code Integration&#xA;05:08 - Unpacking the Differences: Local MCP vs. Hosted MCP vs. CLI&#xA;06:49 - Stage 3: Making Umbraco Packages Agent-Ready with the Base SDK&#xA;07:43 - Stage 4: Scaffolding a Server Using the Five-Phase Software Factory&#xA;09:57 - Stage 5: Advanced MCP Chaining (Proxying, Delegation, and Composite Tools)&#xA;11:07 - Composing Shared Capabilities Across Custom MCP Servers&#xA;11:51 - Stage 6: The New Umbraco in AI Documentation Section&#xA;12:12 - Summary: Lowering Barriers and Reducing Friction for Digital Agencies&#xA;&#xA;Resources and Links:&#xA;Official Umbraco in AI Documentation: https://docs.umbraco.com/umbraco-in-ai&#xA;&#xA;Model Context Protocol (MCP) Core Concepts: https://docs.umbraco.com/umbraco-in-ai/concepts/model-context-protocol&#xA;&#xA;Base MCP Package Guide &amp; Repository Info: https://docs.umbraco.com/umbraco-in-ai/mcp/base-mcp&#xA;&#xA;Developer MCP Server Configurations: https://docs.umbraco.com/umbraco-in-ai/mcp/cms-developer-mcp&#xA;&#xA;Umbraco AI strategy: www.umbraco.com/ai &#xA;&#xA;Umbraco Official CMS Resources: www.umbraco.com]]></description>
                    <pubDate>Thu, 25 Jun 2026 10:11:03 Z</pubDate>
                        <category>hq</category>
                        <category>youtube</category>
                </item>
                <item>
                    <guid>https://www.youtube.com/watch?v=PmSAsJMs_lw</guid>
                    <title>Unboxing Umbraco 18</title>
                    <link>https://www.youtube.com/watch?v=PmSAsJMs_lw</link>
                    <description><![CDATA[Join us for a developer&#x27;s perspective on Umbraco 18, the new Standard-Term Support release of the CMS.&#xA;&#xA;We discuss the new Elements feature, typed OpenAPI schemas for the Delivery API, and the move from Swashbuckle to Microsoft.AspNetCore.OpenApi.&#xA;&#xA;We also look at features you may have missed in recent Umbraco 17 minors, and explain the plan for Umbraco 17 - the current Long-Term Support release.&#xA;&#xA;Chapters: &#xA;00:00 Introduction&#xA;00:51 Releases review&#xA;02:50 A look at Elements&#xA;14:06 Typed OpenAPI schemas for the Delivery API&#xA;18:29 Moving from Swashbuckle to Microsoft.AspNetCore.OpenApi&#xA;21:10 The new login screen!&#xA;23:30 Umbraco 17 minors review&#xA;23:51 Umbraco 17.4 changes for AI&#xA;27:36 Upgrade considerations&#xA;29:21 Finding more information&#xA;&#xA;&#xA;Related resources: &#xA;Dive into the Umbraco 18 final release blog post: [URL]&#xA;&#xA;Visit our Umbraco 18 product page: https://umbraco.com/products/umbraco-cms/umbraco-18/&#xA;&#xA;Ready to learn more? Explore the Umbraco 18 documentation: https://docs.umbraco.com/umbraco-cms&#xA;&#xA;Specific documentation links:&#xA;Version-specific upgrade instructions: https://docs.umbraco.com/umbraco-cms/18.latest/get-started/upgrading-and-migrating/version-specific&#xA;&#xA;Umbraco 18 Release Candidate blog post: https://umbraco.com/blog/umbraco-18-release-candidate/&#xA;&#xA;Laura&#x27;s blog post on migrating away from Swashbuckle: https://dev.to/lauraneto/umbraco-18-and-openapi-a-heads-up-for-extension-developers-1k7&#xA;&#xA;Filip&#x27;s product update from Codegarden: https://umbraco.com/blog/umbraco-product-updatecodegarden-keynote-highlights-q2-2026/&#xA;&#xA;Andy Butland&#x27;s CMS Roadmap talk from Codegarden: https://www.youtube.com/watch?v=HO0BsEebTys]]></description>
                    <pubDate>Thu, 25 Jun 2026 10:10:54 Z</pubDate>
                        <category>hq</category>
                        <category>youtube</category>
                </item>
                <item>
                    <guid>https://codeshare.co.uk/blog/clean-starter-kit-v8-released/</guid>
                    <title>Clean Starter Kit v8 Released</title>
                    <link>https://codeshare.co.uk/blog/clean-starter-kit-v8-released/</link>
                    <description><![CDATA[Clean Starter Kit v8 released for Umbraco 18. Explore the new element library features, block list labels workaround, and runtime migration solution for categories.]]></description>
                    <pubDate>Thu, 25 Jun 2026 08:07:26 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/krebil.umbracoazuresearch</guid>
                    <title>Krebil.UmbracoAzureSearch</title>
                    <link>https://marketplace.umbraco.com/package/krebil.umbracoazuresearch</link>
                    <description><![CDATA[Plug Azure AI Search into Umbraco Search as a fully-featured provider: filtering, faceting, sorting, culture/segment variants, and protected content out of the box.]]></description>
                    <pubDate>Thu, 25 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://umbraco.com/blog/umbraco-18-release/</guid>
                    <title>Umbraco 18 Release</title>
                    <link>https://umbraco.com/blog/umbraco-18-release/</link>
                    <description><![CDATA[The latest Major Release of Umbraco is here: Umbraco 18. Including Phase One of Elements for reusable content management, and typed OpenAPI schemas for the Delivery API. Upgrade today]]></description>
                    <pubDate>Thu, 25 Jun 2026 00:00:00 Z</pubDate>
                        <category>hq</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.memberlogin</guid>
                    <title>Umbraco.Community.MemberLogin</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.memberlogin</link>
                    <description><![CDATA[Sign in to the front-end as a member from the Umbraco backoffice, with optional culture and redirect page, opening in a new tab.]]></description>
                    <pubDate>Thu, 25 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://www.nurhakkaya.com/2026/06/im-umbraco-mvp-for-fifth-year-running.html</guid>
                    <title>I&#x27;m an Umbraco MVP for the fifth year running!</title>
                    <link>https://www.nurhakkaya.com/2026/06/im-umbraco-mvp-for-fifth-year-running.html</link>
                    <description><![CDATA[Every year, Umbraco recognises the people who have gone above and beyond with their contributions to Umbraco projects and community, and I am pleased to announce that I am honoured to be renewed as an Umbraco MVP for the fifth consecutive year.&amp;nbsp;To celebrate this achievement, I also wrote an article which you can read here.&amp;nbsp;Thank you, Umbraco, and the Umbraco community, for their fantastic support in making this happen once more! #h5yr&amp;nbsp;]]></description>
                    <pubDate>Wed, 24 Jun 2026 14:04:05 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://www.youtube.com/watch?v=4hKRsNnKzkY</guid>
                    <title>Phil Whittaker, Umbraco in AI</title>
                    <link>https://www.youtube.com/watch?v=4hKRsNnKzkY</link>
                    <description><![CDATA[In this session from Codegarden, Phil Whittaker explores the strategic vision and practical application of Umbraco in an AI-first world. The discussion details how AI agents and Large Language Models (LLMs) interact with the CMS outside of the traditional backoffice environment using shared best practices.&#xA;&#xA;The presentation covers the architectural shift from a base Model Context Protocol (MCP) server to a chained MCP architecture. By reducing technical friction, developers can enable AI agents to assist directly with content modeling, site deployment, and day-to-day management tasks.&#xA;&#xA;This video is designed for Umbraco developers, digital agencies, and content editors looking to integrate AI orchestration into modern web development. As agentic workflows become standard, learning how to build composable AI skills and deploy deterministic workflows ensures your digital experiences remain maintainable and future-proof.&#xA;&#xA;Key Takeaways:&#xA;- Augmentation over Automation: Focusing on how developers and AI can collaborate effectively rather than replacing human expertise.&#xA;&#xA;- The Open-Source Advantage: Why Umbraco&#x27;s transparent architecture makes it uniquely positioned for efficient AI model training and context comprehension.&#xA;&#xA;- Streamlining the Pitch Phase: Using the Umbraco UI library within design tools to prototype backoffice extensions rapidly.&#xA;&#xA;- The MCP Software Factory: Combining deterministic CLI phases and probabilistic AI phases to scaffold, build, and test custom MCP servers.&#xA;&#xA;- Chained and Remote MCPs: Establishing cross-connector collaboration between external tools (like Google Drive) and Umbraco to manage content at scale.&#xA;&#xA;Timeline Chapters:&#xA;00:00 - Introduction to Umbraco in AI&#xA;01:40 - The Evolution of AI and Agentic Products&#xA;03:03 - Strategy for Reducing Friction with AI Agents&#xA;04:56 - Open Source as an AI Advantage&#xA;06:59 - Leveraging AI in the Product Pitch Phase&#xA;11:56 - Implementing Backoffice Extension Skills&#xA;14:33 - AI in Production: Content Modeling and Implementation&#xA;21:32 - The Role of the Community AI Team&#xA;22:23 - Building Umbraco MCP Servers via Software Factories&#xA;27:07 - Architecture of Chained MCPs&#xA;29:03 - The AI-Accelerated Editor Experience&#xA;33:14 - Practical Prompts and Cross-Connector Collaboration&#xA;36:22 - Hosting Options: Umbraco Cloud and Cloudflare Workers&#xA;38:00 - Custom Editor Workflows and Deterministic Processes&#xA;42:46 - Building for Future Capabilities and Conclusion&#xA;&#xA;Resources and Links&#xA;Umbraco AI Initiatives &amp; Product Pages: https://umbraco.com/products/ai/&#xA;&#xA;Latest Umbraco Product Update: https://umbraco.com/blog/umbraco-product-updatecodegarden-keynote-highlights-q2-2026/ &#xA;&#xA;Umbraco in AI documentation: https://docs.umbraco.com/umbraco-in-ai&#xA;&#xA;Codegarden: https://codegarden.umbraco.com/]]></description>
                    <pubDate>Wed, 24 Jun 2026 11:15:38 Z</pubDate>
                        <category>hq</category>
                        <category>youtube</category>
                </item>
                <item>
                    <guid>https://www.johanreitsma.com/blogs/validating-an-umbraco-13-to-17-upgrade-with-a-sitemap-audit/</guid>
                    <title>Validating an Umbraco 13 to 17 Upgrade with a Sitemap Audit</title>
                    <link>https://www.johanreitsma.com/blogs/validating-an-umbraco-13-to-17-upgrade-with-a-sitemap-audit/</link>
                    <description><![CDATA[How I used a small .NET console tool to crawl a sitemap, compare Umbraco 13 and 17 environments, and quickly find broken pages after an upgrade....]]></description>
                    <pubDate>Wed, 24 Jun 2026 10:54:04 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://www.linkedin.com/pulse/you-never-know-whatll-stick-briony-mckenzie-2bjie/</guid>
                    <title>You Never Know What&#x27;ll Stick</title>
                    <link>https://www.linkedin.com/pulse/you-never-know-whatll-stick-briony-mckenzie-2bjie/</link>
                    <description><![CDATA[On unconventional career paths, accidental dev tools, and great people. There]]></description>
                    <pubDate>Wed, 24 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/lait.umbraco.content.draganddrop</guid>
                    <title>Lait.Umbraco.Content.DragAndDrop</title>
                    <link>https://marketplace.umbraco.com/package/lait.umbraco.content.draganddrop</link>
                    <description><![CDATA[Drag-and-drop and keyboard reordering for the Umbraco backoffice Content tree, plus the ability to drag an item out of a collection (list view) and drop it anywhere in the content tree. Three-zone drop targets, cross-parent moves, a move-in-progress spinner and WCAG-compliant keyboard grab &amp; place.]]></description>
                    <pubDate>Wed, 24 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/sa.automate.weatherapi</guid>
                    <title>SA.Automate.WeatherApi</title>
                    <link>https://marketplace.umbraco.com/package/sa.automate.weatherapi</link>
                    <description><![CDATA[WeatherAPI.com connection types and actions for Umbraco Automate. Get the current weather for a location as part of an automation workflow.]]></description>
                    <pubDate>Wed, 24 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://www.dynamicdave.nl/blog/developer-productivity-hacks/</guid>
                    <title>Boost Your Workflow with Umbraco 17: Developer Productivity Hacks</title>
                    <link>https://www.dynamicdave.nl/blog/developer-productivity-hacks/</link>
                    <description><![CDATA[As developers, we&#x2019;re always searching for ways to get our work done faster. New frameworks roll out and promise to make us blazing fast, AI tools keep booming with talk about writing half our code, and if you&#x2019;ve ever sat through a developer conference lately, you know there&#x2019;s always a session on &#x201C;How to be More Productive.&#x201D; But after working with Umbraco since version 4, I have to be honest: those massive productivity leaps don&#x2019;t really come from the shiny, new, revolutionary tools. It all comes down to friction. And not the dramatic, show-stopping kind. I mean those hundreds of tiny speed bumps scattered all over your day. A few extra clicks in the Umbraco backoffice. Rebuilding the same component again and again. Always double-checking a property alias. Waiting for your solution to spin up. Poring over a monster Razor file, desperately trying to recall where you put that chunk of markup. None of these feel like deal-breakers on their own, but stacked together? Suddenly, you&#x2019;re delivering features at a crawl. What&#x2019;s won me over with the latest Umbraco versions, especially Umbraco 17, is just how much more aligned the platform is with standard .NET development. It feels less like you&#x2019;re wrestling with a quirky CMS and more like you&#x2019;re just building .NET applications. There&#x2019;s a real payoff: less fighting the system means more time solving real business problems.Over the years I&#x2019;ve picked up quite a few habits that speed up Umbraco development and make it less painful&#x2014;some are tied directly to Umbraco 17, while others are just hard-earned lessons from a decade of building websites.&amp;nbsp;Here&#x2019;s what&#x2019;s helped the most for me.]]></description>
                    <pubDate>Tue, 23 Jun 2026 22:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://www.youtube.com/watch?v=wx7Qiyi2Y90</guid>
                    <title>Kenn Jacobsen, It&#x27;s Elemental; reuse your content!</title>
                    <link>https://www.youtube.com/watch?v=wx7Qiyi2Y90</link>
                    <description><![CDATA[Discover how upcoming updates to the Umbraco CMS introduce a dedicated, native framework for managing reusable components. This session details the architectural transition away from traditional content tree workarounds toward a structured, centralized approach that optimizes backend performance and editorial control.&#xA;&#xA;Learn about the native Library section and Elements feature launching with Umbraco 18, alongside an early look at the comprehensive block editor integrations scheduled for Umbraco 19. The presentation highlights how these framework changes resolve historical challenges regarding schema inflation, content routing security, and context-switching during development.&#xA;&#xA;Who This Video Is For:&#xA;This session is designed for Umbraco developers, solution architects, and technical content editors managing complex, multi-site, or multi-tenant environments. Understanding these architectural changes ensures teams can design leaner schemas and build intuitive, decoupled component libraries for future projects.&#xA;&#xA;Key Takeaways:&#xA;- Built on Existing Frameworks: Elements utilize familiar native systems like Models Builder and IPublishedElement, ensuring a minimal learning curve for developers.&#xA;&#xA;- Leaner Database Schemas: Eliminates the necessity of duplicating document types for local and global contexts, maintaining uniform rendering pipelines regardless of data origin.&#xA;&#xA;- Native Security and Non-Routable Architecture: Centralized elements do not generate independent URLs or templates, removing template-sniffing risks and Delivery API exposure.&#xA;&#xA;- Segmented Permissions: Dedicated configuration layers separate content tree permissions from library access, reducing administration overhead in tenant environments.&#xA;&#xA;- Strict Control Mechanisms: Content libraries remain strictly opt-in on a per-element-type basis, preventing structural clutter from baseline utility compositions.&#xA;&#xA;Video Chapters:&#xA;00:00 - Introduction and Welcome&#xA;00:22 - Traditional Workarounds for Reusable Content&#xA;01:29 - Editor Friction and Content Tree Workflows&#xA;02:32 - Block Structure and JSON Serialization Challenges&#xA;05:32 - Technical Friction: Routing, Delivery API, and Security&#xA;07:04 - Schema Growth and Component Rendering Complexities&#xA;08:42 - Centralizing Content: Arriving in the New Library Section&#xA;09:44 - Architectural Overview: Sourcing Elements vs Local Blocks&#xA;11:55 - Cross-Context Tracking with the Out-of-Context Link Icon&#xA;14:26 - Element Characteristics: Lifecycles, Permissions, and Multi-Tenancy&#xA;16:52 - Managing Library Control via Opt-In Configurations&#xA;17:29 - Future Scope: Consolidating Editorial Features into the Library&#xA;18:16 - Implementation Roadmap: Umbraco 18 and Umbraco 19 Updates&#xA;18:44 - Live Demo: Implementing and Configuring the Element Picker&#xA;21:48 - Managing Lifecycles, Single-Sourced Editing, and Preview Mode&#xA;28:44 - Technical Preview: Future Block Editor Integrations&#xA;34:12 - Advanced Editorial Control: Disconnecting and Transferring Sourced Elements&#xA;40:59 - Strategic Takeaways and Presentation Wrap-Up&#xA;&#xA;Key Resources and Links:&#xA;Umbraco 18 Release Candidate: https://umbraco.com/blog/umbraco-18-release-candidate/ &#xA;&#xA;Umbraco CMS: https://umbraco.com/products/umbraco-cms/]]></description>
                    <pubDate>Tue, 23 Jun 2026 12:44:00 Z</pubDate>
                        <category>hq</category>
                        <category>youtube</category>
                </item>
                <item>
                    <guid>https://www.youtube.com/watch?v=gtGw-mY3c2U</guid>
                    <title>Matt Brailsford, AI in Umbraco</title>
                    <link>https://www.youtube.com/watch?v=gtGw-mY3c2U</link>
                    <description><![CDATA[Umbraco AI Staff Engineer and Lead Developer, Matt Brailsford, goes beneath the surface of out-of-the-box copilot packages to show how developers can extend the core platform. Using a real-world podcast management system as a blueprint, this technical deep dive demonstrates how to leverage native framework architecture to build tailored client solutions.&#xA;&#xA;The presentation walks through practical implementations of programmatic speech-to-text execution, custom LLM profile isolation, and context layering. Matt illustrates how to inject dynamic data from background systems and empower models to run custom execution tools rather than relying on manual, hard-coded prompt strings.&#xA;&#xA;This video is for Umbraco backend developers, solution architects, and engineering leads looking to solve complex business requirements with generative AI. It details how to move away from rigid chat interfaces and toward resilient, goal-oriented AI agents integrated into back-office event handlers and automation pipelines.&#xA;&#xA;What You Will Learn:&#xA;- How to orchestrate background queuing for long-running LLM tasks without blocking the content-saving process.&#xA;&#xA;- The method for building custom context resource types that auto-generate Umbraco back-office UI elements using C# code attributes.&#xA;&#xA;- How to implement custom AI Tools that give LLMs secure access to external data registries like the HubSpot API.&#xA;&#xA;- The architectural benefits of shifting from step-by-step prompting to goal-oriented AI Agent reasoning.&#xA;&#xA;- Techniques for marrying Umbraco AI with Umbraco Automate to manage custom event triggers, workflow conditioning, and token management.&#xA;&#xA;Chapters:&#xA;00:00 - Introduction &amp; The Core Philosophy of Umbraco AI&#xA;01:52 - Demo Overview: Podcast Management Requirements&#xA;03:49 - Setting up a Background Queue &amp; Loop Prevention&#xA;06:41 - Configuring Connections, LLM Profiles, and Brand Context&#xA;08:02 - Step 1: Programmatic Audio Transcription Implementation&#xA;09:47 - Step 2: Generating Episode Summaries &amp; Show Notes&#xA;12:12 - Debugging LLM Behavior via AI Back Office Logs&#xA;14:04 - Extending Context: Building Custom Resource Types&#xA;18:16 - Always Inject vs. On-Demand Context Configurations&#xA;21:48 - Empowering LLMs via Custom AI Tools &amp; HubSpot API&#xA;29:27 - Shifting to AI Agents for Goal-Oriented Reasoning&#xA;34:54 - Analyzing Agent Decision-Making &amp; Conversation Logs&#xA;37:16 - Integrating Umbraco AI with Umbraco Automate&#xA;41:40 - Custom Triggers, Actions, and Automated Notifications&#xA;44:18 - Summary of Extension Points &amp; Closing Remarks&#xA;&#xA;Links &amp; Resources: &#xA;Umbraco, the agent-ready CMS: https://umbraco.com/products/ai/&#xA;&#xA;Umbraco AI Framework Documentation &amp; Developer Guides: https://docs.umbraco.com/ai-in-umbraco&#xA;&#xA;Umbraco Automate product page: https://umbraco.com/products/add-ons/automate/&#xA;&#xA;Codegarden 2026 Session Schedule &amp; Announcements: https://codegarden.umbraco.com/]]></description>
                    <pubDate>Tue, 23 Jun 2026 09:19:15 Z</pubDate>
                        <category>hq</category>
                        <category>youtube</category>
                </item>
                <item>
                    <guid>https://www.youtube.com/watch?v=Vd1SLvO1pcE</guid>
                    <title>Bolette Kern, Umbraco CMS in the Age of AI</title>
                    <link>https://www.youtube.com/watch?v=Vd1SLvO1pcE</link>
                    <description><![CDATA[Umbraco CMS Product Manager, Bolette Kern, outlines the strategic evolution of content management systems in the era of generative artificial intelligence. Rather than hard-coding trendy, rigid AI features directly into the core platform, Umbraco&#x27;s architecture focuses on establishing an extensible framework built on choice, governance, and structural flexibility.&#xA;&#xA;This session breaks down how organizations can implement AI workflows on their own terms, utilizing localized control profiles, pre-generation data screening, and automated performance testing. It also highlights how the platform is preparing for an ecosystem where external AI agents read, write, and manage content alongside human creators.&#xA;&#xA;This video is for digital agency architects, enterprise development teams, content strategists, and product owners who need to design future-proof content platforms. It provides a technical blueprint for maintaining data privacy, evaluating non-deterministic LLM outputs, and managing concurrent multi-author content changes safely.&#xA;&#xA;What You Will Learn:&#xA;- The structural risks of vendor-locked AI strategies and why platform flexibility acts as a long-term competitive advantage.&#xA;&#xA;- How to configure pre-generation PII guardrails using regular expressions to protect sensitive user data before it reaches external LLMs.&#xA;&#xA;- Methods for quality-checking non-deterministic prompt outputs using automated grading criteria and side-by-side model comparisons.&#xA;&#xA;- The architecture of Model Context Protocol (MCP) servers and open-source agent skills designed to guide AI assistants in writing idiomatic Umbraco code.&#xA;&#xA;- A first look at upcoming core CMS features for real-time editor collaboration, property-level merge resolution, and visual text differentiation within block editors.&#xA;&#xA;Chapters&#xA;00:00 - The Role of a CMS in an Unpredictable Future&#xA;02:04 - Umbraco&#x27;s Two-Track AI Strategy Overview&#xA;03:02 - The Risks of Hard-Coding AI into the CMS Core&#xA;05:15 - Demo: Managing LLM Connections, Profiles, and Contexts&#xA;06:14 - Enforcing PII Guardrails and Content Integrity Rules&#xA;08:36 - Testing and Grading Non-Deterministic AI Prompt Performance&#xA;13:32 - Leveraging the Umbraco AI Foundation for Custom Packages&#xA;15:30 - Track 2: Interfacing with External AI Agents&#xA;17:43 - Open-Source Agent Skills for Best-Practice Code Generation&#xA;22:46 - Model Context Protocol (MCP) Platform Architecture&#xA;26:48 - Demo: Content Orchestration via the Hosted CMS Editor MCP&#xA;31:43 - Automating Content Audits with Global Updates&#xA;35:18 - Core Platform Advantages in a Code-Generation Ecosystem&#xA;38:41 - Roadmap: Property-Level Editor Collaboration &amp; Conflict Resolution&#xA;41:44 - Integrating Visual Diff Views into the Publishing Flow&#xA;&#xA;Links &amp; Resources&#xA;&#xA;Umbraco, the agent-ready CMS: https://umbraco.com/products/ai/the-agent-ready-cms/ &#xA;&#xA;Codegarden: https://codegarden.umbraco.com/]]></description>
                    <pubDate>Tue, 23 Jun 2026 08:19:07 Z</pubDate>
                        <category>hq</category>
                        <category>youtube</category>
                </item>
                <item>
                    <guid>https://dev.to/bernadet/extending-tiptap-in-umbraco-a-real-world-list-example-1hd1</guid>
                    <title>Extending Tiptap in Umbraco &#x2013; a real world list example</title>
                    <link>https://dev.to/bernadet/extending-tiptap-in-umbraco-a-real-world-list-example-1hd1</link>
                    <description><![CDATA[&lt;p&gt;If you&#x27;ve spent any time migrating editors or building rich-text features, you&#x27;ll know Tiptap looks great on paper but sometimes feels a little... minimal compared to what TinyMCE shipped out of the box. At ilionx we&#x27;ve been moving a few large sites to Umbraco 17 and bumped into the same feedback: list style options. Nothing dramatic, just the ability to pick Roman numerals, different bullet shapes, that sort of thing, but enough to make editors ask for the old behavior back.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;So we wrote a small TypeScript extension that adds back list-style variants. It gets built to App_Plugins with Vite, plugs into the UmbTiptapExtensionApiBase and wires up extra toolbar menu items. The actual extension is tiny, it just adds a listStyleType attribute to the list nodes and renders it as inline CSS, but the surrounding bits (icons, toolbar menus, wiring) make the UX feel polished.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Tiptap has solid docs on extending and creating extensions, and Umbraco documents how to register a Tiptap extension, but stitching everything together took a little trial and error. Below is the extension configuration we used. It looks like a lot for a simple feature, but a fair chunk of the files are just icons and small glue code.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&quot;https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmpscmls4o6334edu9dwi.jpg&quot; class=&quot;article-body-image-wrapper&quot;&gt;&lt;img src=&quot;https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmpscmls4o6334edu9dwi.jpg&quot; alt=&quot; &quot; width=&quot;558&quot; height=&quot;581&quot;&gt;&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Let&#x2019;s start with the actual extension definitions in &lt;code&gt;Umbraco-package.json&lt;/code&gt;, where we define 4 extensions:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight json&quot;&gt;&lt;code&gt;&lt;span class=&quot;nl&quot;&gt;&quot;extensions&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;icons&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;alias&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;My.Icons.TiptapListStyle&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;js&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;/App_Plugins/My.TiptapListStyle/list-style-icons.js&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;tiptapExtension&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;alias&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;My.Tiptap.ListStyle&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;api&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;/App_Plugins/My.TiptapListStyle/list-style.tiptap-api.js&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;meta&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;icon&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;icon-ordered-list&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;label&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;List style type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;group&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;#tiptap_extGroup_formatting&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;tiptapToolbarExtension&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;kind&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;menu&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;alias&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;My.Tiptap.Toolbar.OrderedList&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;overwrites&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Umb.Tiptap.Toolbar.OrderedList&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;api&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;/App_Plugins/ My.TiptapListStyle/ordered-list-menu.tiptap-toolbar-api.js&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;forExtensions&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;My.Tiptap.ListStyle&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot; My.Tiptap.OrderedList&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;items&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;      &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;        &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;label&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Numbered list&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;        &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;data&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;        &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;appearance&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;icon&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;icon-ordered-list&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;      &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;      &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;        &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;label&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Numbered list: i, ii, iii&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;        &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;data&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;lower-roman&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;        &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;appearance&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;icon&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;icon-list-style-lower-roman&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;      &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;      &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;definitions&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;here&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &#xA;  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;tiptapToolbarExtension&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;kind&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;menu&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;alias&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot; My.Tiptap.Toolbar.BulletList&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;overwrites&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Umb.Tiptap.Toolbar.BulletList&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;api&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;/App_Plugins/My.TiptapListStyle/bullet-list-menu.tiptap-toolbar-api.js&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;forExtensions&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;My.Tiptap.ListStyle&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Umb.Tiptap.BulletList&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;items&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;      &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;        &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;label&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Bullet list&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;        &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;data&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;        &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;appearance&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;icon&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;icon-bulleted-list&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;      &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;      &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;        &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;label&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Bullet list: circle&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;        &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;data&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;circle&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;        &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;appearance&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;icon&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;icon-list-style-bullet-circle&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;      &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;      &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;//&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;definitions&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;here&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;Here&#x2019;s what we register:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;an icon set (a bunch of tiny SVGs showing what each list style looks like)&lt;/li&gt;&#xA;&lt;li&gt;one Tiptap extension which carries the list-style attribute&lt;/li&gt;&#xA;&lt;li&gt;two toolbar extensions that replace the ordered/bulleted list buttons with menus that expose the variants.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  The icon set&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;The icons are trivial: I asked an AI to generate SVGs for different list markers and put each one in a tiny TypeScript file that exports the SVG string.&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight typescript&quot;&gt;&lt;code&gt;&lt;span class=&quot;cm&quot;&gt;/** Ordered list with lower-roman markers (i, ii, iii). */&lt;/span&gt;&#xA;&lt;span class=&quot;k&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;`&amp;lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;1.75&quot;&amp;gt;&amp;lt;text x=&quot;1&quot; y=&quot;7.5&quot; font-size=&quot;4.5&quot; fill=&quot;currentColor&quot; stroke=&quot;none&quot; font-family=&quot;serif&quot; font-style=&quot;italic&quot;&amp;gt;i.&amp;lt;/text&amp;gt;&amp;lt;path d=&quot;M9 6h12&quot;/&amp;gt;&amp;lt;text x=&quot;1&quot; y=&quot;13.5&quot; font-size=&quot;4.5&quot; fill=&quot;currentColor&quot; stroke=&quot;none&quot; font-family=&quot;serif&quot; font-style=&quot;italic&quot;&amp;gt;ii.&amp;lt;/text&amp;gt;&amp;lt;path d=&quot;M9 12h12&quot;/&amp;gt;&amp;lt;text x=&quot;1&quot; y=&quot;19.5&quot; font-size=&quot;4.5&quot; fill=&quot;currentColor&quot; stroke=&quot;none&quot; font-family=&quot;serif&quot; font-style=&quot;italic&quot;&amp;gt;iii.&amp;lt;/text&amp;gt;&amp;lt;path d=&quot;M9 18h12&quot;/&amp;gt;&amp;lt;/svg&amp;gt;`&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;And a small registry file maps the icon names to those files:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight typescript&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&#xA;  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;    &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&#x27;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;icon-list-style-lower-roman&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&#xA;    &lt;span class=&quot;na&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&#x27;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;./icons/svg-ordered-list-lower-roman.js&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;&#xA;  &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&#xA;    &lt;span class=&quot;c1&quot;&gt;//...&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;These images are purely to make the toolbar menus readable &#x2014; a little UX polish so editors instantly recognise the option they&#x2019;re picking.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&quot;https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwq4cx2w5cdb00ep1rkyq.jpg&quot; class=&quot;article-body-image-wrapper&quot;&gt;&lt;img src=&quot;https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwq4cx2w5cdb00ep1rkyq.jpg&quot; alt=&quot; &quot; width=&quot;305&quot; height=&quot;270&quot;&gt;&lt;/a&gt; &lt;br&gt;&#xA;&lt;a href=&quot;https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy66bsar5ax2iu3fm0ig4.jpg&quot; class=&quot;article-body-image-wrapper&quot;&gt;&lt;img src=&quot;https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy66bsar5ax2iu3fm0ig4.jpg&quot; alt=&quot; &quot; width=&quot;392&quot; height=&quot;313&quot;&gt;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  The Tiptap extension&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;The extension itself is surprisingly compact. It adds a &lt;code&gt;listStyleType&lt;/code&gt; attribute to the built-in &lt;code&gt;orderedList&lt;/code&gt; and &lt;code&gt;bulletList&lt;/code&gt; nodes and serialises it as inline &lt;code&gt;list-style-type&lt;/code&gt; style so the HTML stays portable and renders the same in the backoffice and on the front end.&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight typescript&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Extension&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;UmbTiptapExtensionApiBase&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&#x27;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;@umbraco-cms/backoffice/tiptap&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&#xA;&#xA;&lt;span class=&quot;cm&quot;&gt;/**&#xA; * Extends the built-in orderedList and bulletList nodes with a `listStyleType`&#xA; * attribute that maps to the CSS `list-style-type` property.&#xA; *&#xA; * The attribute is serialised as an inline style so the stored HTML is portable&#xA; * and renders correctly both in the backoffice editor and on the front end.&#xA; */&lt;/span&gt;&#xA;&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ListStyleExtension&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Extension&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&#xA;  &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&#x27;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;listStyle&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&#xA;&#xA;  &lt;span class=&quot;nf&quot;&gt;addGlobalAttributes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&#xA;      &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;        &lt;span class=&quot;na&quot;&gt;types&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&#x27;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;orderedList&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&#x27;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;bulletList&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&#xA;        &lt;span class=&quot;na&quot;&gt;attributes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;          &lt;span class=&quot;na&quot;&gt;listStyleType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;            &lt;span class=&quot;na&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&#xA;            &lt;span class=&quot;na&quot;&gt;parseHTML&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;element&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;element&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;listStyleType&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&#xA;            &lt;span class=&quot;na&quot;&gt;renderHTML&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;attributes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;              &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;attributes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&#x27;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;listStyleType&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{};&lt;/span&gt;&#xA;              &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;`list-style-type: &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;attributes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&#x27;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;listStyleType&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;`&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;&#xA;            &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&#xA;          &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&#xA;        &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&#xA;      &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;&#xA;  &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;&#xA;&#xA;&lt;span class=&quot;k&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ListStyleTiptapExtensionApi&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;UmbTiptapExtensionApiBase&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;  &lt;span class=&quot;nf&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(...&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;ConstructorParameters&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;typeof&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;UmbTiptapExtensionApiBase&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;    &lt;span class=&quot;k&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(...&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&#xA;    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;getTiptapExtensions&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ListStyleExtension&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;&#xA;  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;That&#x2019;s it, the extension maps an attribute to CSS and makes sure works in both front- and backoffice. Nothing scary.&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  The toolbar extensions&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Because ordered and unordered lists are separate toolbar buttons, we overwrite each one with a menu that exposes the style variants. To avoid duplicating logic we put the toolbar behaviour into a single helper and import it from the two small extension files.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Each toolbar menu has to do a few things:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;create a list if the selection isn&#x2019;t in one&lt;/li&gt;&#xA;&lt;li&gt;switch between ordered and bullet lists&lt;/li&gt;&#xA;&lt;li&gt;toggle or set a specific list-style-type and reflect the active state in the menu UI.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;That last bit is where the logic concentrates, the UI needs to show which style is active and allow toggling back to the default behaviour.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The per-list-type extension files look like this:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight typescript&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;createListStyleMenuToolbarApi&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&#x27;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;./list-style-menu-toolbar-api.js&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&#xA;&#xA;&lt;span class=&quot;k&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;createListStyleMenuToolbarApi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&#x27;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;bulletList&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;And the shared toolbar helper contains the actual implementation and state logic:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight typescript&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Editor&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&#x27;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;@umbraco-cms/backoffice/tiptap&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&#xA;&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;UmbTiptapToolbarElementApiBase&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&#x27;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;@umbraco-cms/backoffice/tiptap&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&#xA;&#xA;&lt;span class=&quot;kd&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ListStyleMenuItem&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?:&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;&#xA;&#xA;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getStyleType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ListStyleMenuItem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;undefined&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&#xA;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;applyListStyle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&#xA;  &lt;span class=&quot;nx&quot;&gt;editor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Editor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&#xA;  &lt;span class=&quot;nx&quot;&gt;listType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&#x27;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;orderedList&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&#x27;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&#x27;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;bulletList&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&#xA;  &lt;span class=&quot;nx&quot;&gt;styleType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;  &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;editor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;isActive&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;listType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;    &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;currentStyle&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;editor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getAttributes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;listType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&#x27;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;listStyleType&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&#xA;    &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;newStyle&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;currentStyle&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;styleType&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;styleType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&#xA;    &lt;span class=&quot;nx&quot;&gt;editor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;chain&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;focus&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;updateAttributes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;listType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;listStyleType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;newStyle&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;&#xA;    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&#xA;  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&#xA;  &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;listType&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&#x27;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;orderedList&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;    &lt;span class=&quot;nx&quot;&gt;editor&lt;/span&gt;&#xA;      &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;chain&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&#xA;      &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;focus&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&#xA;      &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;toggleOrderedList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&#xA;      &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;updateAttributes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&#x27;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;orderedList&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;listStyleType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;styleType&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;&#xA;      &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;&#xA;  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;    &lt;span class=&quot;nx&quot;&gt;editor&lt;/span&gt;&#xA;      &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;chain&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&#xA;      &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;focus&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&#xA;      &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;toggleBulletList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&#xA;      &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;updateAttributes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&#x27;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;bulletList&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;listStyleType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;styleType&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;&#xA;      &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;&#xA;  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&#xA;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;applyDefaultList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;editor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Editor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;listType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&#x27;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;orderedList&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&#x27;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&#x27;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;bulletList&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;  &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;editor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;isActive&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;listType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;    &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;currentStyle&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;editor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getAttributes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;listType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&#x27;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;listStyleType&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&#xA;    &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;currentStyle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;      &lt;span class=&quot;nx&quot;&gt;editor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;chain&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;focus&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;updateAttributes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;listType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;listStyleType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;&#xA;      &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;    &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;listType&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&#x27;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;orderedList&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;      &lt;span class=&quot;nx&quot;&gt;editor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;chain&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;focus&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;toggleOrderedList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;      &lt;span class=&quot;nx&quot;&gt;editor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;chain&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;focus&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;toggleBulletList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&#xA;  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&#xA;  &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;listType&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&#x27;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;orderedList&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;    &lt;span class=&quot;nx&quot;&gt;editor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;chain&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;focus&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;toggleOrderedList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;&#xA;  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;    &lt;span class=&quot;nx&quot;&gt;editor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;chain&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;focus&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;toggleBulletList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;&#xA;  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&#xA;&lt;span class=&quot;cm&quot;&gt;/**&#xA; * Toolbar menu API for ordered/bullet list buttons with list-style-type variants.&#xA; */&lt;/span&gt;&#xA;&lt;span class=&quot;k&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;createListStyleMenuToolbarApi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;listType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&#x27;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;orderedList&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&#x27;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&#x27;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;bulletList&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;UmbTiptapToolbarElementApiBase&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;    &lt;span class=&quot;nx&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;isActive&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;editor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Editor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ListStyleMenuItem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;boolean&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;      &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;editor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&#xA;&#xA;      &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;styleType&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getStyleType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&#xA;      &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;styleType&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;undefined&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;editor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;isActive&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;listType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&#xA;      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&#xA;      &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;styleType&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;        &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;currentStyle&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;editor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getAttributes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;listType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&#x27;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;listStyleType&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;kr&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&#xA;        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;editor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;isActive&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;listType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;currentStyle&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&#xA;      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&#xA;      &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;editor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;isActive&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;listType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;listStyleType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;styleType&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&#xA;    &lt;span class=&quot;nx&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;editor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Editor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ListStyleMenuItem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;      &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;editor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&#xA;&#xA;      &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;styleType&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getStyleType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&#xA;      &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;styleType&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;undefined&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;styleType&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;        &lt;span class=&quot;nf&quot;&gt;applyDefaultList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;editor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;listType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&#xA;        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&#xA;      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&#xA;      &lt;span class=&quot;nf&quot;&gt;applyListStyle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;editor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;listType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;styleType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;  &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  TODO / caveats&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;I&#x2019;m still getting comfortable with TypeScript, so this isn&#x27;t a 100%-polished extension. One known quirk: clicking a custom style button after setting a style will clear the style but not fully remove the list node the way the stock ordered/bullet button does. It&#x27;s a small UX edge-case and likely fixable by tweaking the toggle logic, but I haven&#x27;t had time for it yet.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;If you want to copy this approach, the important bits are:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;expose a &lt;code&gt;listStyleType&lt;/code&gt; attribute on the list nodes,&lt;/li&gt;&#xA;&lt;li&gt;serialize it in a way that works in both editor and front end (inline style is the simplest)&lt;/li&gt;&#xA;&lt;li&gt;replace the toolbar buttons with menus that set/update that attribute.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;Hopefully this saves you a few hours of experimentation. The overall idea is small, but the payoff for editors is surprisingly nice.&lt;/p&gt;]]></description>
                    <pubDate>Tue, 23 Jun 2026 07:37:36 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://umbraco.com/blog/the-pragmatic-enterprise-balancing-ai-innovation-with-predictable-tco/</guid>
                    <title>The Pragmatic Enterprise: Balancing AI Innovation with Predictable TCO</title>
                    <link>https://umbraco.com/blog/the-pragmatic-enterprise-balancing-ai-innovation-with-predictable-tco/</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Tue, 23 Jun 2026 00:00:00 Z</pubDate>
                        <category>hq</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/knowit.umbraco.editorlock</guid>
                    <title>Knowit.Umbraco.EditorLock</title>
                    <link>https://marketplace.umbraco.com/package/knowit.umbraco.editorlock</link>
                    <description><![CDATA[Prevents two editors from changing the same content node at the same time. When a node is already open, a second editor gets a read-only view with a red border and can either Request access (the current editor is prompted to accept or decline) or Force access (an immediate takeover with confirmation). Locks auto-release when the holder disconnects or goes idle, so nodes never get stuck. Real-time over SignalR.]]></description>
                    <pubDate>Tue, 23 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/sa.automate.pushover</guid>
                    <title>SA.Automate.Pushover</title>
                    <link>https://marketplace.umbraco.com/package/sa.automate.pushover</link>
                    <description><![CDATA[Pushover connection type and action for Umbraco Automate. Send notifications to Pushover as part of an automation workflow.]]></description>
                    <pubDate>Tue, 23 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/sa.automate.ntfy</guid>
                    <title>SA.Automate.Ntfy</title>
                    <link>https://marketplace.umbraco.com/package/sa.automate.ntfy</link>
                    <description><![CDATA[ntfy connection types and actions for Umbraco Automate. Send notifications to ntfy as part of an automation workflow.]]></description>
                    <pubDate>Tue, 23 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://www.linkedin.com/pulse/my-first-codegarden-ai-umbraco-17-18-why-im-excited-build-murthy-3ncxe/</guid>
                    <title>My First CodeGarden: AI, Umbraco 17 and 18, and Why I</title>
                    <link>https://www.linkedin.com/pulse/my-first-codegarden-ai-umbraco-17-18-why-im-excited-build-murthy-3ncxe/</link>
                    <description><![CDATA[This was my first time travelling to Copenhagen, and my first ever CodeGarden, and what a way to start. I went over with Luca Colella and Kat Dixon and we had a brilliant couple of days.]]></description>
                    <pubDate>Tue, 23 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://github.com/limbo-works/Limbo.Umbraco.Video/releases/tag/v17.0.0-alpha001</guid>
                    <title>Limbo.Umbraco.Video 17.0.0-alpha001</title>
                    <link>https://github.com/limbo-works/Limbo.Umbraco.Video/releases/tag/v17.0.0-alpha001</link>
                    <description><![CDATA[Package serving as a base for Limbo&#x27;s video picker packages.]]></description>
                    <pubDate>Mon, 22 Jun 2026 18:05:01 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                </item>
                <item>
                    <guid>https://www.youtube.com/watch?v=TRGFLqq711g</guid>
                    <title>Bjarke Berg, Running Umbraco in a Changing World</title>
                    <link>https://www.youtube.com/watch?v=TRGFLqq711g</link>
                    <description><![CDATA[Umbraco Cloud Lead, Bjarke Berg, delivers a technical keynote at Codegarden 2026 detailing the operational realities of hosting web platforms in a shifting threat and traffic landscape. With automated bot scanning and AI-driven probes doubling overall platform requests to 10 billion monthly hits, legacy hosting defaults are no longer sufficient to guarantee stability.&#xA;&#xA;The presentation reviews a year of infrastructure updates driven by a core philosophy of user self-service. Key product rollouts include edge-enriched performance analytics via Cloudflare, custom fallback error pages, granular carbon tracking APIs through direct Azure integration, and dedicated compute load balancing powered by out-of-process Redis caching.&#xA;&#xA;Who This Video Is For:&#xA;This session is designed for technical architects, systems administrators, backend developers, and digital agencies operating Umbraco infrastructure. It provides actionable best practices on platform protection, explains the performance impacts of production runtime mode configurations, and maps out the platform&#x27;s architectural transition to containerized, CI/CD-aligned artifact deployments.&#xA;&#xA;Key Takeaways:&#xA;- How automated bot traffic has shifted platform demands and why edge network DOS mitigation is mandatory.&#xA;&#xA;- The security and performance implications of compiling views using Production Runtime Mode settings.&#xA;&#xA;- How to configure custom fallback pages, localized maintenance windows, and proactive alert rules using webhooks.&#xA;&#xA;- The mechanics of load balancing using out-of-process Redis caching under sticky session configurations.&#xA;&#xA;- The upcoming Artifact Deployment model designed for external CI/CD pipelines and zero-downtime rolling updates.&#xA;&#xA;- Umbraco&#x2019;s long-term infrastructure roadmap moving toward multicloud availability, containerization, and Linux hosting environments.&#xA;&#xA;Chapters:&#xA;00:00 - Introduction &amp; Self-Service Strategy&#xA;02:12 - Traffic &amp; Performance Edge Analytics&#xA;06:11 - Custom Error Pages &amp; Sustainability Dashboards&#xA;08:07 - Load Balancing &amp; Redis Caching Configurations&#xA;10:42 - Scaling Under 2026 Bot &amp; Automated Traffic Pressures&#xA;12:50 - Security Foundations &amp; DOS Mitigation&#xA;15:33 - Maximizing Performance via Production Runtime Mode&#xA;17:22 - Web Application Firewalls &amp; Content Caching Headers&#xA;23:17 - Clean Repositories &amp; Configuration Best Practices&#xA;24:28 - Proactive Uptime Monitoring &amp; Webhook Alert Rules&#xA;27:15 - Scheduled Maintenance Windows by Timezone&#xA;31:07 - Architectural Shift: Introducing Artifact Deployments&#xA;35:10 - Read-Only Schema Controls &amp; Automated Pull Requests&#xA;37:27 - Unlocking Zero-Downtime Rolling Updates&#xA;38:42 - Long-Term Horizon: Multicloud, Containers, and Linux&#xA;&#xA;Links &amp; Resources:&#xA;Umbraco Cloud product page: https://umbraco.com/products/umbraco-cloud/&#xA;&#xA;Umbraco for Enterprise Solutions: https://umbraco.com/products/umbraco-for-enterprise/&#xA;&#xA;Umbraco Product Update q2, 2026: https://umbraco.com/blog/umbraco-product-updatecodegarden-keynote-highlights-q2-2026/ &#xA;&#xA;Codegarden Sessions &amp; Announcements: https://codegarden.umbraco.com/]]></description>
                    <pubDate>Mon, 22 Jun 2026 11:23:06 Z</pubDate>
                        <category>hq</category>
                        <category>youtube</category>
                </item>
                <item>
                    <guid>https://www.youtube.com/watch?v=ThgXALBfU-g</guid>
                    <title>Umbraco Codegarden Keynote, 2026: Mats Persson, Emma Bustow &amp; Filip Bech-Larsen</title>
                    <link>https://www.youtube.com/watch?v=ThgXALBfU-g</link>
                    <description><![CDATA[This keynote kicks off the flagship annual event, Codegarden, bringing together the global community to look back at a milestone year and preview what lies ahead for the ecosystem.&#xA;&#xA;The presentation is hosted by Umbraco CEO Mats Persson, Umbraco CTO Filip Bech-Larsen, and Head of Developer Relations Emma Burstow. Together, they outline recent growth metrics, international initiatives, and shifting developer dynamics across the ecosystem.&#xA;&#xA;The keynote is split into distinct parts. First, Emma and Mats cover community milestones, international office expansion, and business achievements. Following their segment, Filip steps into a solo keynote presentation focusing on core technical updates, massive platform architecture updates, and major product announcements.&#xA;&#xA;WHO THIS VIDEO IS FOR&#xA;This video is essential viewing for Umbraco developers, solutions architects, agency partners, open-source contributors, and technology leaders. Staying aligned with the platform&#x2019;s core engineering choices ensures your teams can plan upgrades accurately, adopt native AI capabilities securely, and design future-proof, composable architectures.&#xA;&#xA;TIMESTAMPS&#xA;Part 1: Community &amp; Business Milestones (Mats &amp; Emma)&#xA;00:00 - Welcome to Codegarden 2026 &amp; Opening Remarks&#xA;&#xA;01:00 - Speaker Introductions &amp; Record-Breaking Attendance Figures&#xA;&#xA;02:02 - The Infamous Pre-Conference Social Bike Ride Recap&#xA;&#xA;04:40 - Global Footprint: Meetups, Festivals, and the New Melbourne Office&#xA;&#xA;07:20 - AI Hackathons &amp; &quot;Vibe Coding&quot; Innovation Era&#xA;&#xA;15:08 - Guest Segment: Top Hackathon Packages Showcase with Lottie Pitcher&#xA;&#xA;19:08 - Maturing the Marketplace: Platform Strategy, Search, and Vendor Trust&#xA;&#xA;26:23 - Breakout Sessions &amp; Community Roadmap Overview&#xA;&#xA;29:55 - Community Teams &amp; Feedback-Driven Development&#xA;&#xA;32:28 - 2026 Most Valuable People (MVP) Awards Ceremony&#xA;&#xA;Part 2: Product Keynote &amp; Technical Announcements (Filip)&#xA;39:35 - Part 2 Intro: Balancing Developer Love with Business Trust&#xA;&#xA;42:05 - Enterprise Security: ISO 27001 Certification &amp; Cloud 100% SLA Policies&#xA;&#xA;43:25 - CMS Core: Umbraco 17 LTS Overview &amp; Umbraco 13 EOL Timeline&#xA;&#xA;45:16 - Architectural Shifts: Entity Framework (EF Core) &amp; Search Abstraction 1.0&#xA;&#xA;46:50 - Content Modeling: Introducing Native &quot;Elements&quot; &amp; Feature Demo&#xA;&#xA;51:50 - The Umbraco AI Framework: Guiding Principles &amp; Architecture&#xA;&#xA;55:15 - Model Context Protocol (MCP) Server &amp; Hosted Remote MCP for Cloud (Beta)&#xA;&#xA;58:10 - Data Privacy &amp; Testing: Microsoft Extensions AI, Guardrails, and Base Models&#xA;&#xA;1:03:05 - Community Innovation: AI Log Analyzer Feature Demo&#xA;&#xA;1:04:52 - Extending the UI: Semantic AI Search, Voice Mode, and Copilot Upgrades&#xA;&#xA;1:08:10 - Major Announcement: Native Workflow Engine (&quot;Umbraco Automate&quot;)&#xA;&#xA;1:16:32 - Composable Architecture: Umbraco Compose &amp; Injection Upgrades&#xA;&#xA;1:21:56 - Platform Add-ons: Engage Personalization, Forms Analytics, and Commerce Scale&#xA;&#xA;1:25:44 - Cloud Portal Infrastructure: Live Edge Insights &amp; Gamified Recommendations&#xA;&#xA;1:31:26 - Major Announcement: Direct Architecture Load Balancing on Umbraco Cloud&#xA;&#xA;KEY TAKEAWAYS&#xA;A New Class of Content: The debut of &quot;Elements&quot; as a fourth native type introduces clean, non-routable, reusable content models managed via a central Library Section, drastically improving author workflows.&#xA;&#xA;Umbraco Automate: The release of built-in low-code workflow automation allows developers and editors to map triggers (like saving content or uploading media) directly to chain-linked actions, API webhooks, and AI pipelines.&#xA;&#xA;Remote MCP Integration: The Model Context Protocol is shifting to a fully hosted cloud structure this summer, granting secure backend developer contexts to AI tools without complex local token installations.&#xA;&#xA;Direct Cloud Load Balancing: Starting July 1st, Umbraco Cloud will support single-click multi-instance scaling backed by dedicated Redis caching tiers to ensure infrastructure elasticity.&#xA;&#xA;OFFICIAL LINKS &amp; RESOURCES&#xA;Umbraco Product Homepage: www.umbraco.com&#xA;&#xA;Codegarden 2026 keynote highlight Blog Post: https://umbraco.com/blog/umbraco-product-updatecodegarden-keynote-highlights-q2-2026/ &#xA;&#xA;Explore the Umbraco Marketplace: https://marketplace.umbraco.com/ &#xA;&#xA;Community Announcements &amp; Upcoming Events: https://community.umbraco.com/&#xA;&#xA;Codegarden website: https://codegarden.umbraco.com/ &#xA;&#xA;Read the Umbraco Code of Conduct: [Insert Link]]]></description>
                    <pubDate>Mon, 22 Jun 2026 10:51:13 Z</pubDate>
                        <category>hq</category>
                        <category>youtube</category>
                </item>
                <item>
                    <guid>https://www.youtube.com/watch?v=LWtYvcAalac</guid>
                    <title>Arnold Visser, Build. Scale. Grow. From Running Projects to Growing Portfolios with Umbraco Cloud.</title>
                    <link>https://www.youtube.com/watch?v=LWtYvcAalac</link>
                    <description><![CDATA[Umbraco Head of Business Development, Arnold Visser, discusses the operational evolution of managing large client portfolios. While digital agencies have traditionally excelled at building individual Umbraco projects, long-term success requires a shift toward managing, supporting, and scaling those assets as business-critical platforms.&#xA;&#xA;This presentation details how Umbraco Cloud and the Umbraco Enterprise offering are changing to support agencies beyond the initial launch phase. By introducing deeper runtime diagnostics, isolated dedicated tiers at lower price points, and flexible licensing options, the ecosystem aims to minimize the hours development teams spend on infrastructure maintenance and deployment coordination.&#xA;&#xA;This video is for digital agency executives, account managers, technical architects, and project managers handling multiple live Umbraco environments. It provides a strategic look at moving away from reactive server management toward a mature, portfolio-wide operational framework that protects client uptime and uncovers ongoing growth opportunities.&#xA;&#xA;What You Will Learn:&#xA;&#xA;- The operational inflection points that occur when an agency scales from 5 to more than 50 active projects.&#xA;&#xA;- Core updates to Umbraco Cloud, including Load Balancing, 90 days of edge traffic insights, custom branded maintenance pages, and ISO 27001 compliance.&#xA;&#xA;- Commercial adjustments to the platform, such as lower-cost entry tiers for dedicated resources and the introduction of an agency-wide Umbraco Deploy license.&#xA;&#xA;- The mid-term technical roadmap covering proactive health alerting via webhooks, automated scaling, and customizable maintenance windows.&#xA;&#xA;- How to leverage artifact deployments and container-based infrastructure to execute rolling updates without client site downtime.&#xA;&#xA;Chapters:&#xA;00:00 - Introduction: The Portfolio Gap&#xA;01:42 - The Shift from Building to Operating Platforms&#xA;02:52 - Build vs. Scale vs. Grow Framework&#xA;04:45 - The Tribal Knowledge Trap at 50&#x2B; Projects&#xA;05:45 - The Role of Umbraco Cloud Infrastructure&#xA;06:57 - Umbraco for Enterprise Overview&#xA;08:48 - Solving Common Operational Challenges&#xA;11:01 - Addressing Partner Feedback on Visibility and Costs&#xA;12:38 - Traffic Performance Insights and Runtime Data&#xA;14:04 - Plan Extensions and Custom Maintenance Pages&#xA;17:01 - New Dedicated Scaling Options and Lower Pricing&#xA;19:46 - Umbraco Deploy Agency Licensing&#xA;21:11 - The Unified Umbraco Partner Portal&#xA;23:08 - Operational Roadmap: Alerting, Webhooks, and Metrics&#xA;26:21 - Artifact Deployment, Rolling Updates, and Containers&#xA;&#xA;Links &amp; Resources:&#xA;Umbraco Cloud product page: https://umbraco.com/products/umbraco-cloud/&#xA;&#xA;Umbraco for Enterprise Solutions: https://umbraco.com/products/umbraco-for-enterprise/&#xA;&#xA;Umbraco Product Update q2, 2026: https://umbraco.com/blog/umbraco-product-updatecodegarden-keynote-highlights-q2-2026/ &#xA;&#xA;Codegarden Sessions &amp; Announcements: https://codegarden.umbraco.com/]]></description>
                    <pubDate>Mon, 22 Jun 2026 10:28:07 Z</pubDate>
                        <category>hq</category>
                        <category>youtube</category>
                </item>
                <item>
                    <guid>https://www.youtube.com/watch?v=HO0BsEebTys</guid>
                    <title>Andy Butland, Our Roadmap, Your CMS  Umbraco 17 Released and What We&#x27;re Building Next</title>
                    <link>https://www.youtube.com/watch?v=HO0BsEebTys</link>
                    <description><![CDATA[Umbraco Head of CMS, Andy Butland, shares a comprehensive update on the CMS platform ecosystem. This session highlights the post-launch reception of the Umbraco 17 LTS release and provides a technical overview of what to expect in the Umbraco 18 launch.&#xA;&#xA;The presentation details how the development team balances new feature work with core platform performance. Key focus areas include back-office rendering optimizations, advanced caching strategies, and foundational upgrades designed to streamline both the developer and content editor experience.&#xA;&#xA;This video is for Umbraco developers, architects, and content managers who want to understand the platform&#x27;s current trajectory. It offers practical technical insights into optimization configurations like Production Runtime Mode and maps out structural shifts for future major releases.&#xA;&#xA;What You Will Learn&#xA;&#xA;- The core capabilities of reusable content elements and type-safe schemas in Umbraco 18.&#xA;&#xA;- How recent performance tuning reduced backend requests by 40% and cut high-latency load times.&#xA;&#xA;- Best practices for configuring Production Runtime Mode and smart Output Caching.&#xA;&#xA;- Ongoing architectural migrations, including the transition to EF Core and Examine search updates.&#xA;&#xA;- Future roadmap goals for variant media, block personalization, and multi-editor collaboration safety.&#xA;&#xA;Chapters&#xA;00:00 - Introduction &amp; Umbraco 18 Overview&#xA;00:26 - Reusable Content Elements in v18&#xA;02:01 - Delivery API &amp; Type-Safe Schemas&#xA;02:44 - Upgrading to v18 &amp; OpenAPI Changes&#xA;04:52 - Umbraco 17 LTS Updates &amp; Adoption&#xA;05:45 - Back Office Request &amp; Loading Performance&#xA;09:14 - Server Operations &amp; Cache Optimizations&#xA;12:50 - Production Runtime Mode Best Practices&#xA;14:28 - Smart Output Caching &amp; Customization&#xA;17:38 - Lightweight External Members for High Concurrency&#xA;20:47 - Quality of Life Wins for Editors &amp; Developers&#xA;27:08 - AI-Assisted Coding &amp; Code Quality Management&#xA;34:09 - Roadmap: Elements Phase 2 &amp; Library Upgrades&#xA;35:20 - Technical Shift: Migration to EF Core&#xA;38:15 - Future Features: Variant Media &amp; Collaboration&#xA;&#xA;Links &amp; Resources&#xA;&#xA;Umbraco CMS: https://umbraco.com/products/umbraco-cms/&#xA;&#xA;Umbraco Product Update Q2: https://umbraco.com/blog/umbraco-product-updatecodegarden-keynote-highlights-q2-2026/&#xA;&#xA;Umbraco CMS documentation: https://docs.umbraco.com/umbraco-cms &#xA;&#xA;Examine Search Abstraction Package: [Insert Link]&#xA;&#xA;Umbraco Documentation &amp; Latest Releases: [Insert Link]]]></description>
                    <pubDate>Mon, 22 Jun 2026 08:57:50 Z</pubDate>
                        <category>hq</category>
                        <category>youtube</category>
                </item>
                <item>
                    <guid>https://umbracocommunity.social/@CorneHoskam/116792346368820033</guid>
                    <title>&quot;We Need to Go Deeper: Extending Umbraco&#x27;s Extensions&quot; Codegarden workshop now available as an escape room</title>
                    <link>https://umbracocommunity.social/@CorneHoskam/116792346368820033</link>
                    <description><![CDATA[&#x1F527; We turned our Codegarden workshop into an escape room.Ronald Barendse, Nathan Woulfe and I ran &quot;We Need to Go Deeper: Extending Umbraco&#x27;s Extensions&quot;, four hours of coding quests across Engage, Workflow and Deploy, each one unlocking a fragment of a bigger puzzle.And here&#x27;s the thing... you can play it too! The whole workshop is public, so clone the repo and work through the quests at your own pace. &#x1F447;https://cornehoskam.com/posts/extending-umbracos-extensions-a-codegarden-workshop-you-can-try-yourself/#umbraco #codegarden #dotnet #extensions]]></description>
                    <pubDate>Mon, 22 Jun 2026 07:48:45 Z</pubDate>
                        <category>community</category>
                        <category>social</category>
                        <category>mastodon</category>
                </item>
                <item>
                    <guid>https://umbuntu.uk/blog/codegarden-2026-ubuntu</guid>
                    <title>Codegarden 2026: Ubuntu</title>
                    <link>https://umbuntu.uk/blog/codegarden-2026-ubuntu</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Mon, 22 Jun 2026 06:44:08 Z</pubDate>
                        <category>blog</category>
                        <category>community</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/kontainer.umbraco</guid>
                    <title>kontainer.umbraco</title>
                    <link>https://marketplace.umbraco.com/package/kontainer.umbraco</link>
                    <description><![CDATA[Adds a media picker to pick media items from a Kontainer repository]]></description>
                    <pubDate>Mon, 22 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://33b6c16b-3387-4d68-9090-4cb1f20ea7b3.azurewebsites.nethttps://owain.codes/blog/2026/june/its-coffee-time/</guid>
                    <title>It&#x27;s Coffee Time!</title>
                    <link>https://33b6c16b-3387-4d68-9090-4cb1f20ea7b3.azurewebsites.nethttps://owain.codes/blog/2026/june/its-coffee-time/</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Mon, 22 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://umbraco.com/blog/uprofile-june-2026-ben-szymanski/</guid>
                    <title>uProfile June 2026 - Ben Szymanski</title>
                    <link>https://umbraco.com/blog/uprofile-june-2026-ben-szymanski/</link>
                    <description><![CDATA[From restoring vintage Macs to catching waves and building backoffice magic - meet 2026 Umbraco MVP Ben Szymanski.]]></description>
                    <pubDate>Mon, 22 Jun 2026 00:00:00 Z</pubDate>
                        <category>hq</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://owain.codes/blog/2026/june/its-coffee-time/</guid>
                    <title>It&#x27;s Coffee Time!</title>
                    <link>https://owain.codes/blog/2026/june/its-coffee-time/</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Mon, 22 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://owaincodes.uksouth01.umbraco.io/blog/2026/june/its-coffee-time/</guid>
                    <title>It&#x27;s Coffee Time!</title>
                    <link>https://owaincodes.uksouth01.umbraco.io/blog/2026/june/its-coffee-time/</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Mon, 22 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://markmcdonald.dev/writing/what-codegarden-inspired-me-to-build-next/</guid>
                    <title>What Codegarden Inspired Me to Build Next</title>
                    <link>https://markmcdonald.dev/writing/what-codegarden-inspired-me-to-build-next/</link>
                    <description><![CDATA[What I learned building an AI-assisted pipeline that maps existing sites into reusable Umbraco components.]]></description>
                    <pubDate>Mon, 22 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://cornehoskam.com/posts/extending-umbracos-extensions-a-codegarden-workshop-you-can-try-yourself/</guid>
                    <title>Extending Umbraco&#x27;s Extensions: A Codegarden Workshop You Can Try Yourself</title>
                    <link>https://cornehoskam.com/posts/extending-umbracos-extensions-a-codegarden-workshop-you-can-try-yourself/</link>
                    <description><![CDATA[Clone and try our four-hour Codegarden workshop on extending Umbraco&#x27;s extensions: an escape room of coding quests across Engage, Workflow and Deploy.]]></description>
                    <pubDate>Mon, 22 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://www.linkedin.com/pulse/most-interesting-thing-codegarden-wasnt-feature-adam-shallcross-cmxwe/</guid>
                    <title>The most interesting thing at CodeGarden wasn</title>
                    <link>https://www.linkedin.com/pulse/most-interesting-thing-codegarden-wasnt-feature-adam-shallcross-cmxwe/</link>
                    <description><![CDATA[There were plenty of shiny things to look at this year. New content types, a workflow engine, hosted servers you can spin up in minutes.]]></description>
                    <pubDate>Mon, 22 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://umbuntu.uk/blog/codegarden-2026-ubuntu/</guid>
                    <title>Codegarden 2026: Ubuntu</title>
                    <link>https://umbuntu.uk/blog/codegarden-2026-ubuntu/</link>
                    <description><![CDATA[&quot;I am because we are&quot;]]></description>
                    <pubDate>Mon, 22 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/frontendsupport.partialtextstring</guid>
                    <title>FrontendSupport.PartialTextString</title>
                    <link>https://marketplace.umbraco.com/package/frontendsupport.partialtextstring</link>
                    <description><![CDATA[Basically a TextString, but you can specify prefix and/or postfix strings to show, which can make it much easier to understand exactly what&#x27;s supposed to go into the field.]]></description>
                    <pubDate>Sat, 20 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/lait.umbraco.analytics.plausible</guid>
                    <title>Lait.Umbraco.Analytics.Plausible</title>
                    <link>https://marketplace.umbraco.com/package/lait.umbraco.analytics.plausible</link>
                    <description><![CDATA[Surfaces Plausible Analytics tracking data inside the Umbraco backoffice: a Content dashboard and a per-page block on each document&#x27;s Info tab.]]></description>
                    <pubDate>Sat, 20 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/lait.umbraco.ui.scrolltofield</guid>
                    <title>Lait.Umbraco.UI.ScrollToField</title>
                    <link>https://marketplace.umbraco.com/package/lait.umbraco.ui.scrolltofield</link>
                    <description><![CDATA[A table of contents navigation helper for the Umbraco backoffice. Adds a dockable outline panel to the document editor that lists the page&#x27;s tabs, property groups and Block List / Block Grid items &#x2014; so editors keep their overview and can jump straight to any section on long content pages. Click an entry to scroll it into view and highlight it.]]></description>
                    <pubDate>Sat, 20 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://mastodon.social/@greystate/116774972921955847</guid>
                    <title>Spin up Umbraco websites quickly with Umbeasy</title>
                    <link>https://mastodon.social/@greystate/116774972921955847</link>
                    <description><![CDATA[Need to spin up an #Umbraco website for a quick test of something?Try the friction-free #Umbreasy &#x26A1;&#x1F3C3;&#x200D;&#x2642;&#xFE0F;&#x200D;&#x27A1;&#xFE0F;It&#x27;s in beta right now: https://umbreasy.com]]></description>
                    <pubDate>Fri, 19 Jun 2026 04:51:47 Z</pubDate>
                        <category>community</category>
                        <category>social</category>
                        <category>mastodon</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/esatto.umbraco.backoffice.redirects</guid>
                    <title>Esatto.Umbraco.Backoffice.Redirects</title>
                    <link>https://marketplace.umbraco.com/package/esatto.umbraco.backoffice.redirects</link>
                    <description><![CDATA[Dead-URL &#x2192; new-URL redirects for Umbraco 17. Provides a SQL-backed Redirects table, a Settings-section dashboard for editors to manage 301 rules, and an IContentFinder that resolves redirects at request time. A single flat list of redirects: exact case-insensitive matching with query-string preservation, draft rows, and idempotent migrations.]]></description>
                    <pubDate>Fri, 19 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://www.shoutdigital.com/insights/codegarden-2026-and-the-next-chapter-for-umbraco/</guid>
                    <title>Codegarden 2026 and the next chapter for Umbraco | Shout Digital</title>
                    <link>https://www.shoutdigital.com/insights/codegarden-2026-and-the-next-chapter-for-umbraco/</link>
                    <description><![CDATA[AI, automation, community - Umbraco MVP Ian Grieve talks about his key takeaways from Copenhagen.]]></description>
                    <pubDate>Fri, 19 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://www.nathanielnunes.com/blog/umbraco-mvp-codegarden-2026/</guid>
                    <title>Copenhagen, Codegarden, and My First Year as an Umbraco MVP</title>
                    <link>https://www.nathanielnunes.com/blog/umbraco-mvp-codegarden-2026/</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Thu, 18 Jun 2026 17:53:16 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://www.nathanielnunes.com/blog/umbraco-mvp-codegarden-2026</guid>
                    <title>Copenhagen, Codegarden, and My First Year as an Umbraco MVP</title>
                    <link>https://www.nathanielnunes.com/blog/umbraco-mvp-codegarden-2026</link>
                    <description><![CDATA[My first year as an Umbraco MVP: receiving the award at Codegarden 2026 in Copenhagen, the MVP Summit, the sessions, the people, and the moments between.]]></description>
                    <pubDate>Thu, 18 Jun 2026 11:30:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://www.youtube.com/watch?v=FKpbT4LQHd0</guid>
                    <title>Codegarden Aftermovie 2026</title>
                    <link>https://www.youtube.com/watch?v=FKpbT4LQHd0</link>
                    <description><![CDATA[&#x1F430; The Rabbit faced traffic jams, train delays, and several moments of &#x201C;you&#x2019;ve got to be kidding me&#x201D; on the way to Codegarden.&#xA;&#xA;Then: Codegarden.&#xA;&#xA;&#x1F37F; Hit play to see how quickly travel stress turned into community vibes, new friendships, and a reminder that Codegarden isn&#x2019;t just an event.&#xA;&#xA;It&#x2019;s a family reunion that keeps growing &#x1FAF6;&#xA;&#xA;And before your grandma out-plans you and claims that prime summer weekend for her 90th birthday, lock your calendar for 2027: &#x1F475;&#x1F94A;&#xA;&#xA;&#x1F4CD; &#xD8;ksnehallen, Copenhagen &#x1F3F0;&#xA;&#x1F4C5; June 9&#x2013;10, 2027 &#x1F986;&#x1F1E9;&#x1F1F0;]]></description>
                    <pubDate>Thu, 18 Jun 2026 10:39:22 Z</pubDate>
                        <category>hq</category>
                        <category>youtube</category>
                </item>
                <item>
                    <guid>https://owaincodes.uksouth01.umbraco.io/blog/2026/june/codegarden-2026/</guid>
                    <title>Codegarden 2026 recap</title>
                    <link>https://owaincodes.uksouth01.umbraco.io/blog/2026/june/codegarden-2026/</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Thu, 18 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://frytom.org/2026/06/13/tilbake-fra-kobenhavn-og-umbraco-codegarden-2026-%F0%9F%87%A9%F0%9F%87%B0/</guid>
                    <title>Tilbake fra K&#xF8;benhavn og Umbraco Codegarden 2026! &#x1F1E9;&#x1F1F0;</title>
                    <link>https://frytom.org/2026/06/13/tilbake-fra-kobenhavn-og-umbraco-codegarden-2026-%F0%9F%87%A9%F0%9F%87%B0/</link>
                    <description><![CDATA[Noen dager fylt med faglig p&#xE5;fyll, gode samtaler og sterke relasjoner &#x2014; det er alltid noe eget med Codegarden. Umbraco-communityet er ikke en kult, men&amp;#8230; det er kanskje det n&#xE6;rmeste vi kommer &#x2026;]]></description>
                    <pubDate>Thu, 18 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://www.linkedin.com/pulse/my-first-umbraco-codegarden-more-than-stickers-t-shirts-dave-jonker-tew6e/?trackingId=QknJFmSATw6wxaZj0VosrA%3D%3D</guid>
                    <title>My First Umbraco Codegarden: More Than Stickers and T-Shirts</title>
                    <link>https://www.linkedin.com/pulse/my-first-umbraco-codegarden-more-than-stickers-t-shirts-dave-jonker-tew6e/?trackingId=QknJFmSATw6wxaZj0VosrA%3D%3D</link>
                    <description><![CDATA[After my blog was recently featured on umb.fyi &#x2014; thanks to Matt Brailsford for that &#x2014; I felt like I also owed the community a proper write-up about my very first Codegarden experience.]]></description>
                    <pubDate>Thu, 18 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://owain.codes/blog/2026/june/codegarden-2026/</guid>
                    <title>Codegarden 2026 recap</title>
                    <link>https://owain.codes/blog/2026/june/codegarden-2026/</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Thu, 18 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/lait.umbraco.search.typesense</guid>
                    <title>Lait.Umbraco.Search.Typesense</title>
                    <link>https://marketplace.umbraco.com/package/lait.umbraco.search.typesense</link>
                    <description><![CDATA[An extension for Umbraco CMS providing a custom search engine integration with Typesense.]]></description>
                    <pubDate>Thu, 18 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/oc.automate.bluesky</guid>
                    <title>OC.Automate.Bluesky</title>
                    <link>https://marketplace.umbraco.com/package/oc.automate.bluesky</link>
                    <description><![CDATA[Bluesky connection type and action for Umbraco Automate. Post to Bluesky as part of an automation workflow.]]></description>
                    <pubDate>Thu, 18 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://33b6c16b-3387-4d68-9090-4cb1f20ea7b3.azurewebsites.nethttps://owain.codes/blog/2026/june/codegarden-2026/</guid>
                    <title>Codegarden 2026 recap</title>
                    <link>https://33b6c16b-3387-4d68-9090-4cb1f20ea7b3.azurewebsites.nethttps://owain.codes/blog/2026/june/codegarden-2026/</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Thu, 18 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://medium.com/@ravimotha/codegarden-26-a-review-aa35c60e3b08?source=rss-8e76be83b03f------2</guid>
                    <title>Codegarden 26 : a review</title>
                    <link>https://medium.com/@ravimotha/codegarden-26-a-review-aa35c60e3b08?source=rss-8e76be83b03f------2</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Wed, 17 Jun 2026 17:42:48 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://medium.com/@ravimotha/codegarden-26-a-review-aa35c60e3b08?source=rss------umbraco-5</guid>
                    <title>Codegarden 26 : a review</title>
                    <link>https://medium.com/@ravimotha/codegarden-26-a-review-aa35c60e3b08?source=rss------umbraco-5</link>
                    <description><![CDATA[&lt;div class=&quot;medium-feed-item&quot;&gt;&lt;p class=&quot;medium-feed-image&quot;&gt;&lt;a href=&quot;https://medium.com/@ravimotha/codegarden-26-a-review-aa35c60e3b08?source=rss------umbraco-5&quot;&gt;&lt;img src=&quot;https://cdn-images-1.medium.com/max/2160/1*toX2D2qIoJiKh7DBjvlAoQ@2x.jpeg&quot; width=&quot;2160&quot;&gt;&lt;/a&gt;&lt;/p&gt;&lt;p class=&quot;medium-feed-snippet&quot;&gt;Photo by Lukas Rychvalsky on Unsplash&lt;/p&gt;&lt;p class=&quot;medium-feed-link&quot;&gt;&lt;a href=&quot;https://medium.com/@ravimotha/codegarden-26-a-review-aa35c60e3b08?source=rss------umbraco-5&quot;&gt;Continue reading on Medium &#xBB;&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;]]></description>
                    <pubDate>Wed, 17 Jun 2026 17:42:48 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://www.jeroenbreuer.nl/blog/my-codegarden-2026-highlights/</guid>
                    <title>My Codegarden 2026 highlights</title>
                    <link>https://www.jeroenbreuer.nl/blog/my-codegarden-2026-highlights/</link>
                    <description><![CDATA[A summary of my Codegarden 2026 highlights.]]></description>
                    <pubDate>Wed, 17 Jun 2026 14:26:59 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://jcdc.dev/blog/umbraco-package-automate-inspector</guid>
                    <title>Umbraco Package: Automate Inspector</title>
                    <link>https://jcdc.dev/blog/umbraco-package-automate-inspector</link>
                    <description><![CDATA[Explore everything Umbraco Automate has to offer with this new community package!]]></description>
                    <pubDate>Wed, 17 Jun 2026 07:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://www.blendinteractive.com/thoughts/codegarden-2026/</guid>
                    <title>Codegarden 2026 Road Report: Umbraco&#x2019;s Bet on AI and Reusable Content | Blend Interactive</title>
                    <link>https://www.blendinteractive.com/thoughts/codegarden-2026/</link>
                    <description><![CDATA[A road report from Codegarden 2026 &amp;mdash; Umbraco]]></description>
                    <pubDate>Wed, 17 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.youtubepicker</guid>
                    <title>Umbraco.Community.YouTubePicker</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.youtubepicker</link>
                    <description><![CDATA[Custom Umbraco datatype to enable editors to pick YouTube videos or playlists from a specific YouTube channel. You&#x27;ll need a Google account and signup for an API key before you can use it.]]></description>
                    <pubDate>Wed, 17 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://codeshare.co.uk/blog/my-codegarden-2026-experience/</guid>
                    <title>My Codegarden 2026 Experience</title>
                    <link>https://codeshare.co.uk/blog/my-codegarden-2026-experience/</link>
                    <description><![CDATA[My Codegarden 2026 experience: keynotes, talks, awards, and the moments that reminded me why this community matters. Nine years, still getting goosebumps.]]></description>
                    <pubDate>Tue, 16 Jun 2026 02:57:14 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umcontentgenerator</guid>
                    <title>umContentGenerator</title>
                    <link>https://marketplace.umbraco.com/package/umcontentgenerator</link>
                    <description><![CDATA[AI-powered content generation for Umbraco: create fully-populated Block Grid and Block List pages &#x2014; text and images &#x2014; base on template page and short promt, powered by OpenAI.]]></description>
                    <pubDate>Tue, 16 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/esatto.umbraco.backoffice.contenttreedraganddrop</guid>
                    <title>Esatto.Umbraco.Backoffice.ContentTreeDragAndDrop</title>
                    <link>https://marketplace.umbraco.com/package/esatto.umbraco.backoffice.contenttreedraganddrop</link>
                    <description><![CDATA[Native HTML5 drag-and-drop for the Umbraco 17 backoffice Content tree. Adds three-zone (above / into / below) drop targets per row with optimistic same-parent reorder and full cross-parent move support. Pure App_Plugins package &#x2014; no C# code.]]></description>
                    <pubDate>Tue, 16 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://aaronsadler.dev/blog/2026/june/16/codegarden-2026-i-went-to-copenhagen-for-a-week</guid>
                    <title>Codegarden 2026: I went to Copenhagen for a week</title>
                    <link>https://aaronsadler.dev/blog/2026/june/16/codegarden-2026-i-went-to-copenhagen-for-a-week</link>
                    <description><![CDATA[My week in Copenhagen for Codegarden 2026: the MVP Summit, the launch of Umbraco Automate, the sessions that stood out, and why I keep coming back. Continue reading]]></description>
                    <pubDate>Tue, 16 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://dev.to/luukpeters/tiptap-is-not-broken-your-expectations-are-5h8m</guid>
                    <title>TipTap is not broken. Your expectations are.</title>
                    <link>https://dev.to/luukpeters/tiptap-is-not-broken-your-expectations-are-5h8m</link>
                    <description><![CDATA[&lt;p&gt;Since the Umbraco 16 release, Umbraco ships only with the TipTap Rich Text Editor. This was unfortunately something that Umbraco was forced to do. TinyMce 7 has a license that is incompatible with the open source license of Umbraco and TinyMce 6 was going out of support. So an alternative had to be found.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Umbraco did a pretty good job at abstracting the rich text data. In Umbraco 15 both TinyMCE and TipTap were still present and exchangeable because of this abstraction. And arguably, the way you can set up your toolbars for the TipTap editor is superior to TinyMCE. But still, a new Rich Text Editor is a big change that presents real challenges.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;These challenges are most obvious when looking at the Umbraco forum&#x27;s &lt;a href=&quot;https://forum.umbraco.com/tag/tip-tap/78&quot; rel=&quot;noopener noreferrer&quot;&gt;tip-tap tag&lt;/a&gt;. Topics vary, but a few come up again and again:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Additional HTML tags getting added to the markup, like a &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt; tag inside a &lt;code&gt;&amp;lt;li&amp;gt;&lt;/code&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;The inability to add certain tags to TipTap, like &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tags&lt;/li&gt;&#xA;&lt;li&gt;The inability to add styling to an element, for instance to create a link that looks like a button&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;These are valid challenges, especially if you&#x27;re upgrading from an existing TinyMCE setup. But this is also a good moment to ask two questions:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;strong&gt;Why&lt;/strong&gt; do I want the same behaviour?&lt;/li&gt;&#xA;&lt;li&gt;And was the old behaviour actually any good to begin with?&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  You don&#x27;t have to migrate everything at once&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Before getting into that, it&#x27;s worth knowing that TinyMCE is still available as a community package for Umbraco 16&#x2B;. If you&#x27;re in the middle of a project, dealing with a large codebase, or just not ready to rethink your Rich Text Editor setup right now, that&#x27;s a valid escape hatch. Swap in the package, keep things running, and give yourself time to migrate properly.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;But &quot;later&quot; should still be on the roadmap. The package is community maintained, not an official Umbraco product, so there are no guarantees around long-term support or compatibility with future Umbraco versions. Relying on it indefinitely carries the same risk as the situation Umbraco just came out of with TinyMCE 6.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;So use it if you need to. Just don&#x27;t treat it as a permanent solution.&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  The RTE is not a page builder&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;I&#x27;m not a big fan of giving editors too much freedom in a Rich Text Editor. Don&#x27;t get me wrong, RTEs are great and help editors a lot. But give too much rope and things go wrong fast. My preference is for RTEs to handle the basics: adding a link, making text bold or italic, maybe a table if the frontend deals with it gracefully on mobile.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;What I don&#x27;t like is image placement and scaling inside an RTE. Without proper processing this is a problem for performance and mobile layouts. I also don&#x27;t like HTML snippets or trying to add CSS classes to elements from within an editor. It&#x27;s error prone, and if something breaks, you need HTML knowledge to fix it. That&#x27;s not a realistic expectation for most editors.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;So when people ask how to replicate that kind of behaviour in TipTap, I&#x27;d rather ask why they need it at all.&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  Stop fighting the editor, start working with Umbraco&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Instead of trying to make TipTap behave like TinyMCE did, consider using the tools Umbraco already gives you.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Need a link that looks like a button? Use a block inside the Rich Text Editor. TipTap has solid block support, and Umbraco exposes this well. You get a structured piece of content with its own view, its own properties, fully typed, fully renderable. An editor picks a &quot;Button&quot; block, fills in the label and the link and that&#x27;s it. No CSS classes, no raw HTML, no risk of someone pasting &lt;code&gt;style=&quot;color:red&quot;&lt;/code&gt; into a script tag three months later.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Need a pull quote, a callout, a code snippet with syntax highlighting? Same answer. Model it as a block. Render it properly. Keep the RTE itself lean.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The argument I keep hearing is that recreating all of this takes more time than just making the old thing work again. That&#x27;s sometimes true in the short term. But you&#x27;re building something more maintainable, more predictable and more editor-friendly.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;There&#x27;s another reason to think twice before pouring effort into recreating editor-specific behaviour: Umbraco has already switched its default Rich Text Editor once. It could happen again. If your implementation leans heavily on workarounds and editor-specific quirks, you&#x27;re setting yourself up for the same migration pain all over again. If instead your RTE is kept lean and the complex bits live in blocks with their own models and views, a future editor switch becomes much less of an event. The RTE just renders text. Everything interesting is already abstracted away.&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  What about the extra markup?&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;The &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt; inside &lt;code&gt;&amp;lt;li&amp;gt;&lt;/code&gt; is worth addressing separately, because it looks like a bug but it isn&#x27;t. TipTap is built on ProseMirror, which uses a strict document schema where every node needs to contain the right type of child node. For list items, that child is a block node and a paragraph is that block node. This is what makes editing reliable: without it, you can end up in situations where the cursor can&#x27;t be placed inside a list item at all, or where deleting an item breaks unexpectedly.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;This behaviour is not unique to TipTap. Any editor built on ProseMirror does the same thing, and that includes quite a few well-known ones. TinyMCE handled lists differently, but that doesn&#x27;t make TinyMCE&#x27;s approach the correct one.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;If your frontend CSS breaks because of this, that&#x27;s a one-time fix, typically just adjusting margin or display rules on &lt;code&gt;li p&lt;/code&gt;. Once it&#x27;s done, you&#x27;re working with markup that is actually more structurally consistent than what TinyMCE produced.&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  Closing thought&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;A new editor is disruptive. But disruption is also a chance to reconsider decisions that were made years ago under different constraints, maybe with less knowledge of what Umbraco could do, or just because TinyMCE made it easy and easy felt like good enough.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;TipTap is not TinyMCE. It&#x27;s not trying to be. And once you stop expecting it to be, you might find it pushes you toward solutions that are cleaner, better structured and easier to hand off to an editor who has no idea what a DOM is.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Work with the grain of the tool, not against it.&lt;/p&gt;]]></description>
                    <pubDate>Mon, 15 Jun 2026 12:47:24 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://codeshare.co.uk/blog/how-i-hacked-the-sticker-printers-at-codegarden-2026/</guid>
                    <title>How I Hacked the Sticker Printers at Codegarden 2026</title>
                    <link>https://codeshare.co.uk/blog/how-i-hacked-the-sticker-printers-at-codegarden-2026/</link>
                    <description><![CDATA[Discover how constraints sparked innovation at Codegarden 2026. I bypassed printer limitations using only my phone and creative problem-solving techniques.]]></description>
                    <pubDate>Mon, 15 Jun 2026 10:29:21 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://umbracocommunity.social/@owaincodes/116753175751677147</guid>
                    <title>New release for umbPublisher 1.5.1</title>
                    <link>https://umbracocommunity.social/@owaincodes/116753175751677147</link>
                    <description><![CDATA[New release for umbPublisher 1.5.1Tags that are set in #obsidian can now be mapped to #umbraco property editor. Available on https://community.obsidian.md/plugins/umbpublisher]]></description>
                    <pubDate>Mon, 15 Jun 2026 08:43:36 Z</pubDate>
                        <category>community</category>
                        <category>social</category>
                        <category>mastodon</category>
                </item>
                <item>
                    <guid>https://dev.to/d_inventor/i-attended-umbraco-codegarden-2026-5dak</guid>
                    <title>I attended Umbraco Codegarden 2026!</title>
                    <link>https://dev.to/d_inventor/i-attended-umbraco-codegarden-2026-5dak</link>
                    <description><![CDATA[&lt;p&gt;Codegarden was last week in Copenhagen! I was there this time and here are my thoughts about the event. Previous time I attended was in 2023, so I will draw some comparisons to that year. It was a great experience and I left feeling generally excited and inspired.&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  Organization&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Just like previous time, the event was very well-organized. At Codegarden, you&#x27;re always well taken care of with lunch and dinner, great instructions, a little kick-off at the start of every day and a lot of spatial diversity. You always know what to expect.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I was very happy to see that the quiet area was easy to find and it was mentioned at the beginning of the event. The previous time I didn&#x27;t know that such a quiet area existed and I spoke out about that. It gave me comfort that I knew where to retreat to when I needed to. Additionally, there were many places to stand or sit outside and inside. The event was also a little shorter, which made it more manageable for me.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The location was absolutely ideal for the amount of people that attended. There were many attendees (about 700 they said, if I remember correctly), but at no point did the venue feel crowded. I could always easily get to where I wanted to go, there were no long queues and there was always enough seats for all the talks at every stage.&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  Talks&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;I&#x27;ll admit that, on the previous Codegarden, I had the wrong expectations for the talks. Talks are obviously aimed at specific target audiences and I don&#x27;t belong to all of them. Some talks aim to inform, while others aim to inspire. Stories are not tutorials. Also, sometimes a talk doesn&#x27;t teach you something new, but simply validates what you were already doing.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;So it was this time too. My focus is currently shifting slightly away from coding and more towards collaboration and I am looking for inspiration on how to deliver better software faster. I specifically wanted to attend &lt;em&gt;Debugging Teams: What High-Performing Developer Teams Do Differently&lt;/em&gt;, because it seemed relevant to me. Although I was hoping for a deep analysis in development process and teamwork strategies, I ended up learning about the importance of trust and of sharing the &quot;what&quot;, &quot;how&quot; and &quot;why&quot; of what we do. It surely gave me something to think about.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I listened to &lt;em&gt;Building Resilient Umbraco Integrations&lt;/em&gt;. A more tutorial-style demonstration with insightful information about what you need to think about when integrating with external services. The presentation included concrete code examples that gave concrete solutions to the presented problems. I personally already knew all of it, but it was nice to see anyway, because it confirms that I&#x27;m already doing it right.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;A special mention goes to Semira Allen and Jason Wodicka with their talks &lt;em&gt;Drowning in Details: Turning TechTalk Into Everyday Language&lt;/em&gt; and &lt;em&gt;How (not) to mess up everything&lt;/em&gt;. Their talks were incredibly engaging and they were a joy to listen to. I had a good laugh and they were each inspiring in their own ways.&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  Some additional thoughts&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;Copenhagen:&lt;/strong&gt; The fact that it was in Copenhagen was what made me consider it again. I am not big on traveling abroad and the trip to Odense and back was seriously daunting. Being able to get there with just the airplane made the whole trip so much better!&lt;br&gt;&#xA;&lt;strong&gt;AI:&lt;/strong&gt; I haven&#x27;t mentioned AI in this blog. That&#x27;s because I find the ethics of the application of AI at the moment very questionable. I am still working on forming a well-informed opinion. Umbraco and the community have showcased some very impressive work with AI.&lt;br&gt;&#xA;&lt;strong&gt;Umbraco awards:&lt;/strong&gt; In case you didn&#x27;t know it yet: we were nominated for an Umbraco award for &quot;Accessibility and Security&quot;! Even though we didn&#x27;t win the award, I believe that our submission was still the best. The winning solution had a more visible approach to accessibility, but we can show off a real certification of accessibility with end-user testimonies to back it up. The nomination is a nice validation of my team&#x27;s hard work.&lt;br&gt;&#xA;&lt;strong&gt;Umbraco in the bigger picture?&lt;/strong&gt; Right now I am learning from people like &lt;a href=&quot;https://www.youtube.com/@ModernSoftwareEngineeringYT&quot; rel=&quot;noopener noreferrer&quot;&gt;Dave Farley&lt;/a&gt;, &lt;a href=&quot;https://www.youtube.com/@EmilyBache-tech-coach&quot; rel=&quot;noopener noreferrer&quot;&gt;Emily Bache&lt;/a&gt; and &lt;a href=&quot;https://www.youtube.com/channel/UC3RKA4vunFAfrfxiJhPEplw&quot; rel=&quot;noopener noreferrer&quot;&gt;Derek Comartin&lt;/a&gt; about better software development practices. Some of it is more about architecture and some of it is about collaboration and process. I feel like these topics deserve more attention in the Umbraco community. I need a talk named &lt;em&gt;How I upgraded my mid-size web agency from feature branch and PR drag to real CI/CD&lt;/em&gt;. Maybe I get to give this talk myself one day, who knows.&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  Conclusion&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;It was a great event, and I&#x27;m very happy that I could be there. If it&#x27;s like this again next year, then I will be eager to attend. Thank you Umbraco for everything!&lt;/p&gt;]]></description>
                    <pubDate>Mon, 15 Jun 2026 07:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://umbraco.com/blog/across-the-himalayas-and-into-the-heart-of-umbraco/</guid>
                    <title>Across the Himalayas and Into the Heart of Umbraco</title>
                    <link>https://umbraco.com/blog/across-the-himalayas-and-into-the-heart-of-umbraco/</link>
                    <description><![CDATA[Meet Rashmita and Jasper, the founders of One Tech Nepal. Discover how they use their 100% Umbraco agency to fund IT education and libraries in remote Himalayan schools.]]></description>
                    <pubDate>Mon, 15 Jun 2026 00:00:00 Z</pubDate>
                        <category>hq</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/esatto.umbraco.backoffice.sharedpreviewlink</guid>
                    <title>Esatto.Umbraco.Backoffice.SharedPreviewLink</title>
                    <link>https://marketplace.umbraco.com/package/esatto.umbraco.backoffice.sharedpreviewlink</link>
                    <description><![CDATA[Shareable preview links for Umbraco 17. Editors mint a tokenized URL via a workspace-action button; recipients open the URL externally and see the current draft (no backoffice login). Tokens are 7-day data-protected; recipient cookie scopes preview to the specific page for 5 minutes.]]></description>
                    <pubDate>Mon, 15 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/oc.automate.mastodon</guid>
                    <title>OC.Automate.Mastodon</title>
                    <link>https://marketplace.umbraco.com/package/oc.automate.mastodon</link>
                    <description><![CDATA[Mastodon connection type and action for Umbraco Automate. Post statuses to any Mastodon instance as part of an automation workflow.]]></description>
                    <pubDate>Mon, 15 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://33b6c16b-3387-4d68-9090-4cb1f20ea7b3.azurewebsites.nethttps://owain.codes/blog/2026/june/ocautomatemastodon-released/</guid>
                    <title>OC.Automate.Mastodon released</title>
                    <link>https://33b6c16b-3387-4d68-9090-4cb1f20ea7b3.azurewebsites.nethttps://owain.codes/blog/2026/june/ocautomatemastodon-released/</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Mon, 15 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://owain.codes/blog/2026/june/ocautomatemastodon-released/</guid>
                    <title>OC.Automate.Mastodon released</title>
                    <link>https://owain.codes/blog/2026/june/ocautomatemastodon-released/</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Mon, 15 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://owaincodes.uksouth01.umbraco.io/blog/2026/june/ocautomatemastodon-released/</guid>
                    <title>OC.Automate.Mastodon released</title>
                    <link>https://owaincodes.uksouth01.umbraco.io/blog/2026/june/ocautomatemastodon-released/</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Mon, 15 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://www.nevitech.co.uk/blog/codegarden-2026-a-week-in-copenhagen-i-wont-forget/</guid>
                    <title>Codegarden 2026: A Week in Copenhagen I Won&#x27;t Forget</title>
                    <link>https://www.nevitech.co.uk/blog/codegarden-2026-a-week-in-copenhagen-i-wont-forget/</link>
                    <description><![CDATA[Justin reflects on an unforgettable week at Codegarden 2026 in Copenhagen, where he was recognised as an Umbraco MVP, invited on stage during the keynote to demo his AI Log Analyser package, and won the AI Package Award.]]></description>
                    <pubDate>Sun, 14 Jun 2026 23:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://blog.aabech.no/archive/introducing-larsingerlogue-cv-5000/</guid>
                    <title>Introducing Larsingerlogue CV-5000</title>
                    <link>https://blog.aabech.no/archive/introducing-larsingerlogue-cv-5000/</link>
                    <description><![CDATA[&lt;h2&gt;Or how I gave Behringer FCV100 the reference power supply it deserves to use for CV-modulation with Korg Minilogue XD&lt;/h2&gt;&#xA;&lt;p&gt;&lt;em&gt;If you&#x27;re here to solve the problem and don&#x27;t care for a story, keep scrolling, you&#x27;ll get to schematics, breadboard pictures and an ingredient list.&lt;/em&gt;&lt;/p&gt;&#xA;&lt;p&gt;&lt;em&gt;There&#x27;s also a &lt;a href=&quot;#video-montage&quot;&gt;short video montage&lt;/a&gt; for the even more impatient.&lt;/em&gt;&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&quot;https://blog.aabech.no/media/1080/intro-image.png&quot; alt=&quot;A logo with the text Larsingerlogue CV-5000 and an FCV100 connected to a gray box&quot; /&gt;&lt;/p&gt;&#xA;&lt;p&gt;This is quite a different post than I usually make, if I&#x27;m allowed to call it usually anymore at all. In any case, I&#x27;ve been playing the keys in a band for a couple of years and have yearned for a proper synth to supplement my (6) master keyboards. Recently I acquired my first ever analogue synthesizer. It only took 40 years for the dream to come through. I found a 15% cheaper second hand &amp;quot;unused&amp;quot; Korg Minilogue XD. But I only had damper pedals to use with it. Half the fun of synthesizers for me is varying the low pass filter cutoff. It&#x27;s what gives that cool swiping, buzzing or muffled sound depending on how you &amp;quot;turn&amp;quot; it. For that I needed another type of pedal, and not just a regular one.&lt;/p&gt;&#xA;&lt;p&gt;The Minilogue has a ton of hand-controlled potentiometer knobs we can use for a multitude of parameters, amongst others the filter cutoff. However it does not have a regular 1/4&amp;quot; jack slot for expression pedals like keyboards usually have. It has a damper slot, but only for CC64 on/off (sustain on and off). What we want is a full, preferably analogue, range from 0 to 100%. Expression pedals are excellent for this since they&#x27;re basically pot meters you turn with your foot.&lt;/p&gt;&#xA;&lt;p&gt;What the Minilogue comes with are two 1/8&amp;quot; jack &amp;quot;CV in&amp;quot; ports. So I browsed the interwebz for &amp;quot;CV pedal&amp;quot; and found a bunch of alternatives. Since I&#x27;m eyeing a Behringer Poly D come fall I thought the Behringer FCV100 V2 pedal seemed a good deal. It&#x27;s advertised as a volume pedal with a CV option, including reversing polarity. So I ordered one and excitedly unpacked it while the band leader ran out to buy the last 1/8&amp;quot; to 1/8&amp;quot; cable and a 1/8&amp;quot; to 1/4&amp;quot; adapter. I&#x27;d dutifully inserted a 9V battery and optimistically hooked everything up...&lt;/p&gt;&#xA;&lt;p&gt;Nothing!&lt;/p&gt;&#xA;&lt;p&gt;I tried both CV inputs, both polarities, tons of options on the minilogue, but still nothing.&lt;br /&gt;&#xA;When I got home - I plugged a 1/8&amp;quot; into the &lt;em&gt;input&lt;/em&gt; port which according to the interwebs should &amp;quot;power it on&amp;quot;. Still nothing from the CV output. And yes, I &lt;em&gt;had&lt;/em&gt; measured the voltage on the 9V battery.&lt;/p&gt;&#xA;&lt;p&gt;&lt;em&gt;&lt;strong&gt;Note: I have had no ambition doing electronics &amp;quot;right&amp;quot; with this project, nor writing a proper tutorial with a &amp;quot;right&amp;quot; way of doing it. This is a story about fiddling around and getting things to work. It is &lt;em&gt;not&lt;/em&gt; a tutorial in proper electronics, in fact almost the opposite. I have not bothered to look up facts or calculated things. This means people who know their way around electronics might find this article revolting. I&#x27;m sorry. It was a way for me to brush up on how things work and get something working quickly. DIY by fiddling around until it works. Again, sorry, but hopefully other learners might be inspired to both fiddle around &lt;em&gt;and&lt;/em&gt; learn to do the calculations. There&#x27;s even a gem of an insight in the end that only hit me while writing this post. &#x1F607;&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h2&gt;The research&lt;/h2&gt;&#xA;&lt;p&gt;According to the interwebz, someone claimed to have gotten CV output when they had plugged an unconnected 1/8&amp;quot; jack into input 2, but showed no proof or measurements. The next answer was someone who had done some due dilligence and measured the output. Apparently it only works with instruments that feed a reference voltage from its control voltage (CV) &lt;em&gt;input&lt;/em&gt; in order for the pedal to vary it.&lt;/p&gt;&#xA;&lt;p&gt;So I dug out my trusty old multimeter and started the process of dusting off the parts of my brain still remembering reading &lt;a href=&quot;https://www.goodreads.com/book/show/10796575-there-are-no-electrons&quot;&gt;&amp;quot;There are no Electrons: Electronics for Earthlings&amp;quot;&lt;/a&gt; ten plus years ago. I learned about what tip, ring and sleeve (TRS) for jack plugs are, and all the other variants. Measuring DC between the tip and sleeve of the unconnected side of the cable when pressing the pedal did absolutely nothing. Measuring resistance though showed a varying impedance of 0 through 50k&#x3A9;. If I flipped between TRS and RTS mode on the pedal it seemingly reversed the resistance on the ring, but the tip stayed fixed on 50k&#x3A9; in TRS mode. In any case, after some brain clearing with ChatGPT, I could conclude that the pedal in CV mode is &lt;em&gt;only&lt;/em&gt; a 50k&#x3A9; potmeter and does not provide any of the sweet power from the (now useless) 9V battery I had inserted.&lt;/p&gt;&#xA;&lt;p&gt;&lt;em&gt;Note: I&#x27;ve left the pedal in RTS mode. In order to use both and reverse polarity there&#x27;s more research and a V2 to be built. See closer to the end for a short rant about the factory presets in Minilogue XD.&lt;/em&gt;&lt;/p&gt;&#xA;&lt;p&gt;I figured there has to be a way to provide that power even if the synth doesn&#x27;t. So after a little more chatting with ChatGPT I figured I could dig through all my old cables and adapters to find an USB cable and adapter we&#x27;re not using. I should be able to &amp;quot;inject&amp;quot; it&#x27;s 5V DC voltage into the jack cable instead of relying on the synth to provide it. I dug through all my treasure drawers and found an USB mini-B 4-pin (?) to USB A cable and cut off the mini-B plug to reveal the two VCC/GND cables and two data cables. I found a couple of horribly old AC USB adapters and measured the DC from both via the cable&#x27;s red (VCC) and black (GND) wires. One gave 3.3V and the other gave 5V. I happily threw the overdue 3.3V one in the &amp;quot;to recycling&amp;quot; bin and rubbed my hands together over the other. (Throwing out one old device should score me at least one plus in the wife&#x27;s accounting system.)&lt;/p&gt;&#xA;&lt;h2&gt;Specifications&lt;/h2&gt;&#xA;&lt;p&gt;Of course it&#x27;s prudent to actually check the specs of the hardware you&#x27;re trying to shove a current into. So I dug up the details in the manuals, which to be honest are both quite a tad more than averagely vague about how to connect control voltage hardware.&lt;/p&gt;&#xA;&lt;p&gt;The Minilogue XD manual has the following gem of a CV mention:&lt;/p&gt;&#xA;&lt;p&gt;&lt;em&gt;CV IN 1 and 2 jacks (3.5 mm monaural mini-phone jack; input voltage: &#x2013;5V to 5V in modulation mode, &#x2013;3V to 5V in CV/gate mode)&lt;/em&gt;&lt;/p&gt;&#xA;&lt;p&gt;So I figured I&#x27;m safe proceeding with my 0-5V endeavour. We &lt;em&gt;are&lt;/em&gt; going to use it for modulation.&lt;/p&gt;&#xA;&lt;p&gt;The FCV100 manual has a similarly brief description of it&#x27;s &amp;quot;CV&amp;quot; output:&lt;/p&gt;&#xA;&lt;p&gt;&lt;em&gt;1/4&amp;quot; TS - unbalanced Tip: Supply volt. from unit/instr. to be controlled: Impedance: 50kOhm Ring: Slider pick-up (CV dependend on ped. position, impedance: 0-50kOhm)&lt;/em&gt;&lt;/p&gt;&#xA;&lt;p&gt;There&#x27;s some more specs around 2V and output impedance, but as far as I&#x27;ve understood that&#x27;s all about the volume control feature of the pedal. I have a hard time interpreting whether that sentence says &amp;quot;bring your own power&amp;quot; or &amp;quot;we&#x27;ll use the battery you inserted&amp;quot;.&lt;/p&gt;&#xA;&lt;p&gt;Having this information and some support from the [un]trusty LLM though, I pressed on to simulating the imagined setup.&lt;/p&gt;&#xA;&lt;h2&gt;Tinkering&lt;/h2&gt;&#xA;&lt;p&gt;&lt;a href=&quot;https://www.tinkercad.com/&quot;&gt;Tinkercad&lt;/a&gt; is an awesome tool for budding DYIers wanting to learn or experiment with electronics. Especially if starting to experiment with arduinos or other consumer grade microcontrollers. I could safely experiment with placement of the resistors and different resistance values and until I got the desired voltage output on the simulator&#x27;s multimeter.&lt;/p&gt;&#xA;&lt;p&gt;In place of the pedal I added a regular pot meter. It has three pins which is basically a 1:1 representation of the tip, ring and sleeve on a jack plug. The middle pin is the &amp;quot;wiper&amp;quot;, which I&#x27;d measured on the pedal to output a varying resistance between the ring and sleeve on the opposite end of the jack cable.&lt;br /&gt;&#xA;Back and forth with GPT and the multimeter for a while made me understand that the CV input on the Minilogue likely has an internal 1M&#x3A9; or larger resistor, just like a multimeter has. That&#x27;s how it&#x27;s able to read the voltage loss between the sides and thereby also receive the varying &amp;quot;control voltage&amp;quot; input from the pedal.&lt;/p&gt;&#xA;&lt;p&gt;Tinkercad also sports a USB connector and all the resistors you can dream of. And that&#x27;s the whole recipe for this &amp;quot;CV adapter&amp;quot;. It took some time to remember my URIs (Ohm&#x27;s law) and how things affect the dance of the electrons (or little green men if you prefer). To be honest I still don&#x27;t really know, but fiddling and discussing with GPT got me to something that works with a fair understanding. Mr. GPT had suggested a 50 k&#x3A9; resistor between the pedal and synth, but the simulations led me to choose a 10 k&#x3A9;. Again, the learned and/or dilligent would bother to calculate why.&lt;/p&gt;&#xA;&lt;p&gt;The ingredients for the simulation ended up as follows:&lt;/p&gt;&#xA;&lt;table&gt;&#xA;&lt;thead&gt;&#xA;&lt;tr&gt;&#xA;&lt;th&gt;Name&lt;/th&gt;&#xA;&lt;th&gt;Value&lt;/th&gt;&#xA;&lt;th&gt;Description&lt;/th&gt;&#xA;&lt;/tr&gt;&#xA;&lt;/thead&gt;&#xA;&lt;tbody&gt;&lt;tr&gt;&#xA;&lt;td&gt;USB Standard A&lt;/td&gt;&#xA;&lt;td&gt;-&lt;/td&gt;&#xA;&lt;td&gt;USB connector. It gives 5V in the simulator as expected.&lt;/td&gt;&#xA;&lt;/tr&gt;&#xA;&lt;tr&gt;&#xA;&lt;td&gt;Resistor A&lt;/td&gt;&#xA;&lt;td&gt;150 &#x3A9; &lt;br&gt;(several&amp;nbsp;tries)&lt;/td&gt;&#xA;&lt;td&gt;A resistor to limit the circuit current slightly from the USB output. Just to be precaucious.&lt;/td&gt;&#xA;&lt;/tr&gt;&#xA;&lt;tr&gt;&#xA;&lt;td&gt;Resistor B&lt;/td&gt;&#xA;&lt;td&gt;10 k&#x3A9;&lt;/td&gt;&#xA;&lt;td&gt;A resistor to protect and limit the current going into the synth. (We&#x27;d rather not blow it up...)&lt;/td&gt;&#xA;&lt;/tr&gt;&#xA;&lt;tr&gt;&#xA;&lt;td&gt;Fake CV in port&lt;/td&gt;&#xA;&lt;td&gt;1 M&#x3A9;&lt;/td&gt;&#xA;&lt;td&gt;A resistor representing the internal impedance of the synth&#x27;s CV sensor and the tip (VCC) and sleeve (GND) of the jack plug.&lt;/td&gt;&#xA;&lt;/tr&gt;&#xA;&lt;tr&gt;&#xA;&lt;td&gt;Multimeter&lt;/td&gt;&#xA;&lt;td&gt;-&lt;/td&gt;&#xA;&lt;td&gt;A multimeter in resistance mode measuring the loss over the &quot;fake CV in port&quot; resistor.&lt;/td&gt;&#xA;&lt;/tr&gt;&#xA;&lt;tr&gt;&#xA;&lt;td&gt;Fake pedal&lt;/td&gt;&#xA;&lt;td&gt;50 k&#x3A9;&lt;/td&gt;&#xA;&lt;td&gt;A potentiometer representing the pedal and the tip (VCC), ring (CV out), and sleeve (GND) of the jack plug.&lt;/td&gt;&#xA;&lt;/tr&gt;&#xA;&lt;/tbody&gt;&lt;/table&gt;&#xA;&lt;hr /&gt;&#xA;&lt;p&gt;Here&#x27;s the breadboard layout:&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&quot;https://blog.aabech.no/media/1074/larsingerlogue-breadboard-tinkercad.png&quot; alt=&quot;A breadboard layout representing the pedal, extra parts and synth&quot; /&gt;&lt;/p&gt;&#xA;&lt;p&gt;I&#x27;m extremely discontent with how Tinkercad figured to lay out the schematic, but in any case I suppose it is correct. Why couldn&#x27;t the pot go straight to the 10k resistor? Oh well, here&#x27;s it is in all it&#x27;s jumbled glory:&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&quot;https://blog.aabech.no/media/1077/larsingerlogue-schematic-tinkercad.png&quot; alt=&quot;An electronic shematic representing the pedal, extra parts and synth&quot; /&gt;&lt;/p&gt;&#xA;&lt;h2&gt;Prototyping and building in real life&lt;/h2&gt;&#xA;&lt;p&gt;Having the simulation show thumbs up I figured I should try it in real life and do some measurements before hooking anything up to my brand new synth. For some reason Tinkercad shows a tiny explosion on the USB connector when the simulation starts, but my adapter stood the test and I suspect there might be a bug with the implementation on Tinkercad. &#x1F607;&lt;/p&gt;&#xA;&lt;p&gt;I have both breadboards and a plethora of resistors lying around from my Arduino adventures last decade. Finding a breadboard and some resistors didn&#x27;t bide much problem. They&#x27;re all within arms length to my left. But this is where I started going back and forth between the breadboard and Tinkercad. Turns out real life didn&#x27;t give the same measurements as the simulation. Even if I used a PSU of 5.5V instead of a USB connector. My adapter gives 5.5V, remember?&lt;/p&gt;&#xA;&lt;p&gt;Here&#x27;s a little montage of all the crocodiles holding things together.&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&quot;https://blog.aabech.no/media/1073/larsingerlogue-breadboard-prototype.png&quot; alt=&quot;Picture montage showing a breadboard, wires, crocodile clips and a multimeter&quot; /&gt;&lt;/p&gt;&#xA;&lt;p&gt;After a while I had the right resistors to see 0-5V on the multimeter having hooked up the pedal to my shortest mangled jack-cable. I excitedly hooked up some crocodiles to the other half-jack and the breadboard, wearily shoved the plug into my synth and tried the pedal. Sucess! The LCD-display on the synth showed 0 to ... 97%??? So even if the simulator and my multimeter showed I output 5V from the pedal when 100% down the Minilogue expects more. Anyone knowledgeable with electronics will likely know why, but I merely suspect that it somehow &amp;quot;feels&amp;quot; the max input from the source is 5.5V. So it was out with the jack, out with the GND crocodile and in and out with misc initial resistors until I saw 0-100% CV input on the synth. A 150 &#x3A9; resistor turned out to be the sweet spot.&lt;/p&gt;&#xA;&lt;p&gt;I now had proof I could build this &amp;quot;CV-adapter&amp;quot;, so it was time for V1.&lt;/p&gt;&#xA;&lt;h2&gt;Assembling V1&lt;/h2&gt;&#xA;&lt;p&gt;Again from my Arduino-days I found a few circuit boards in my drawers. The smallest ones were 24x18 holes (7x3cm) - a little big. But incidentally I could spot in the corner of my eye something resembling an Arduino-case.  The 7x3 board fits perfectly within, and it&#x27;s a slim one just 1.5cm tall. Perfect!&lt;/p&gt;&#xA;&lt;p&gt;On to the soldering. Not that I lacked any space, but it&#x27;s always nice not having to cross wires. Enter a slightly unorthodox tool, my favorite program in the whole world: Excel. Who needs technical drawing software when you have colorable cells? I first drew up the layout on the left, but inspecting the casing I&#x27;d found I figured I&#x27;d rather flip it around. So I ended up going for the layout on the right.&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&quot;https://blog.aabech.no/media/1079/larsingerlogue_soldering_sketch.png&quot; alt=&quot;Excel sketches of the soldered circuit board&quot; /&gt;&lt;/p&gt;&#xA;&lt;p&gt;I&#x27;m extremely shaky, so soldering took its time. It&#x27;s somewhat of a Zen excercise I&#x27;ve never quite mastered. I also realized way too late (of course) that I&#x27;d been better off stretching a few more wires, but hey - it&#x27;s 10 years since last time I did anything like this.&lt;/p&gt;&#xA;&lt;p&gt;In any case, the first test with the multimeter and pedal showed a semi-constant 5.4V so I had to go back to the soldering board. A few connection tests with the trusty meter showed a lacking connection to ground from the pedal. Even with my new &amp;quot;computer glasses&amp;quot; &lt;em&gt;and&lt;/em&gt; a magnifyer on my little helper I couldn&#x27;t see that the amputated resistor leg I&#x27;d connected to ground wasn&#x27;t connected. But I could find the &lt;em&gt;spot&lt;/em&gt; where the connection ended, so I added kind of a highway of tin all the way. Success!&lt;/p&gt;&#xA;&lt;p&gt;Here&#x27;s how the circuitboard ended up.&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&quot;https://blog.aabech.no/media/1078/larsingerlogue-soldered-circuit.png&quot; alt=&quot;Picture showing of a soldered circuit board&quot; /&gt;&lt;/p&gt;&#xA;&lt;p&gt;The final stretch was to have the board rest well within the box. I was lucky to find some double sided tape in the kitchen, and since one side of the board already rested slighly on the USB and jack cables I chuckled as I cut off another 2.5cm piece of the now 4cm long USB mini cord. It fit perfectly. Tape on the case, tape on the board, and a short piece of USB mini cord as a pillow.&lt;/p&gt;&#xA;&lt;p&gt;Here&#x27;s the final box.&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&quot;https://blog.aabech.no/media/1076/larsingerlogue-final-box.png&quot; alt=&quot;Picture of a box connected to the FCV100&quot; /&gt;&lt;/p&gt;&#xA;&lt;h2&gt;Final fun&lt;/h2&gt;&#xA;&lt;p&gt;Of course my box needed a name and a logo. It didn&#x27;t take many brain-iterations until I landed on Larsingerlogue CV-5000. It&#x27;s &lt;em&gt;my&lt;/em&gt; [Behr]&lt;strong&gt;inger&lt;/strong&gt; [FCV100 to Mini]&lt;strong&gt;logue&lt;/strong&gt;[ XD] &lt;strong&gt;CV-5&lt;strong&gt;[V * 1]&lt;/strong&gt;000&lt;/strong&gt;[mA adapter]. I turned to my age old friend &amp;quot;Impact&amp;quot; and quickly found a fitting gradient in Photoshop.&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&quot;https://blog.aabech.no/media/1075/larsingerlogue-cv-5000.png&quot; alt=&quot;Larsingerlogue CV-5000 logo in fat lettering with a retro colored gradient.&quot; /&gt;&lt;/p&gt;&#xA;&lt;h3&gt;Video montage&lt;/h3&gt;&#xA;&lt;p&gt;I&#x27;d also shot a couple of videos and pictures during the process, so I amused myself by throwing together a short video of the whole process. It features the first built in patch of Minilogue XD and it&#x27;s sample sequence with me &amp;quot;playing&amp;quot; the filter cutoff on the now functioning pedal, and the &amp;quot;riser&amp;quot; delay time and depth using my free hand. Farily cool. And then a quite off-beat attempt at the Stranger Things theme as an RL demo of the final product. Check it out.&lt;/p&gt;&#xA;&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/nTTtX-T8_dE?si=M1ZUYMwnrk0mNLtL&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen&gt;&lt;/iframe&gt;&#xA;&lt;p&gt;I hope you&#x27;ve anjoyed following my little story of dipping my toes in electronics for music. There&#x27;s high potential for a V2 with better polarity support, and who knows what other ideas one might come up with for 100% &amp;quot;DIY&amp;quot; effects to shove into those CV inputs. There&#x27;s still one unused. &#x1F601;&lt;/p&gt;&#xA;&lt;h3&gt;Grief&lt;/h3&gt;&#xA;&lt;p&gt;My only grief, and that&#x27;s kind of connected to the single polarity of my adapter, is that &lt;em&gt;all&lt;/em&gt; of the built-in patches in the Minilogue XD are set to having CV 1 modulating the shape of VCO 1 from 0 to 100%, and CV 2 is set to filter cutoff from 0 to -100%. That means I open the filter by &amp;quot;closing&amp;quot; the pedal and close the filter by &amp;quot;opening&amp;quot; the pedal. Pedal to the floor means almost no audible sound.&lt;/p&gt;&#xA;&lt;h3&gt;Learning while blogging&lt;/h3&gt;&#xA;&lt;p&gt;In hindsight I think I just realized with writing this that 5V on the multimeter means (almost) &lt;em&gt;no&lt;/em&gt; power moves through the resistor, which is measured as 0V - while I&#x27;ve been reading 5V (loss) on the multimeter. That would explain the &amp;quot;weird&amp;quot; direction of the pot meter in the simulation that&#x27;d been bugging me. &#x1F923;&lt;/p&gt;&#xA;&lt;p&gt;But hey - adds to a fun story about learning and just jumping into the water.&lt;/p&gt;&#xA;&lt;p&gt;If you got this far I hope you had a chuckle, nodded or otherwise found this interesting.&lt;br /&gt;&#xA;Thanks a lot for reading, and have fun whatever endeavor led you to this post.&lt;/p&gt;]]></description>
                    <pubDate>Sun, 14 Jun 2026 21:24:09 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/esatto.umbraco.backoffice.dictionaryfiltervalues</guid>
                    <title>Esatto.Umbraco.Backoffice.DictionaryFilterValues</title>
                    <link>https://marketplace.umbraco.com/package/esatto.umbraco.backoffice.dictionaryfiltervalues</link>
                    <description><![CDATA[Extends the Umbraco 17 backoffice Dictionary section filter to also match translation VALUES, not just dictionary-item names. Useful for editors who remember a translated string but not the dictionary key. Adds one authenticated Management API endpoint and a backoffice entry point that re-points the built-in Dictionary collection&#x27;s data source at it &#x2014; no window.fetch patching, no anonymous endpoints.]]></description>
                    <pubDate>Sat, 13 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/esatto.umbraco.backoffice.customeditors</guid>
                    <title>Esatto.Umbraco.Backoffice.CustomEditors</title>
                    <link>https://marketplace.umbraco.com/package/esatto.umbraco.backoffice.customeditors</link>
                    <description><![CDATA[A library of reusable property editor UIs for the Umbraco backoffice. Ships an Encrypted Textbox editor (encrypts sensitive values at rest via ASP.NET Core Data Protection, masked on screen) and a Date Range editor (two inline calendars with start/end constraint, optional time and min/max bounds).]]></description>
                    <pubDate>Sat, 13 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://www.dynamicdave.nl/blog/my-first-umbraco-codegarden/</guid>
                    <title>My First Umbraco Codegarden: More Than Stickers and T-Shirts</title>
                    <link>https://www.dynamicdave.nl/blog/my-first-umbraco-codegarden/</link>
                    <description><![CDATA[After my blog was recently featured on umb.fyi &#x2014; thanks to Matt Brailsford for that &#x2014; I felt like I also owed the community a proper write-up about my very first Codegarden experience.Because honestly, after finally attending for the first time, I completely understand why people keep talking about it long after the event is over.I&#x2019;ve been building with Umbraco since version 4&#x2014;that takes me back to 2012 or maybe 2013. After all those years, I finally made the pilgrimage: my first Codegarden. And wow, I get it now. I see why people talk about this thing like it&#x2019;s some annual family reunion you can&#x2019;t miss, not just a conference. All the stories you hear&#x2014;about the talks, the people, those late nights that blur into early mornings&#x2014;they&#x27;re all real. Still, the heart of it isn&#x2019;t just scavenging for stickers or filling your suitcase with t-shirts. It&#x2019;s something deeper.What really struck me&#x2014;and it hit pretty much as soon as I walked through the doors&#x2014;is that sense of belonging. Suddenly you realize you&#x2019;re a piece of something much bigger than just a CMS, a project, or a logo. You&#x2019;re dropped right into the Umbraco community, and it&#x2019;s almost impossible not to get swept up in that feeling.]]></description>
                    <pubDate>Fri, 12 Jun 2026 22:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://www.youtube.com/watch?v=bmfrLgNfQ_g</guid>
                    <title>umbraCoffee - LIVE at #Codegarden 2026!</title>
                    <link>https://www.youtube.com/watch?v=bmfrLgNfQ_g</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Fri, 12 Jun 2026 02:29:10 Z</pubDate>
                        <category>community</category>
                        <category>youtube</category>
                </item>
                <item>
                    <guid>https://www.wearediagram.com/blog/diagram-wins-2026-umbraco-award-best-enterprise-solution</guid>
                    <title>Diagram and NATP Win Best Enterprise Solution at the 2026 Umbraco Awards</title>
                    <link>https://www.wearediagram.com/blog/diagram-wins-2026-umbraco-award-best-enterprise-solution</link>
                    <description><![CDATA[We&#x2019;re excited to share that the National Association of Tax Professionals (NATP) website, designed and developed by Diagram, has been named Best Enterprise Solution at the &#xA; 2026 Umbraco Awards.&amp;nbsp;]]></description>
                    <pubDate>Thu, 11 Jun 2026 20:46:10 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/ripplepreview</guid>
                    <title>RipplePreview</title>
                    <link>https://marketplace.umbraco.com/package/ripplepreview</link>
                    <description><![CDATA[See your actual pages while you edit them. Blocks render through your site&#x27;s own views, styles and scripts &#x2014; sections render whole with their children, carousels and animations run, and everything stays editable: hover to highlight a block inside the preview and click to open it.]]></description>
                    <pubDate>Thu, 11 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.aiagentmemory</guid>
                    <title>Umbraco.Community.AiAgentMemory</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.aiagentmemory</link>
                    <description><![CDATA[AI Agent Memory for Umbraco &#x2014; persistent memory &#x2B; learning layer for Umbraco&#x27;s AI agent stack. Editors give thumbs-up / thumbs-down feedback on agent runs via the AI Agent Feedback widget; the package indexes that feedback as searchable memory and injects it into subsequent runs so agents suppress false positives and reuse validated patterns. Composes on Umbraco.AI 1.8&#x2B; (vector store via Umbraco.AI.Search). Memory is off by default; per-agent opt-in via appsettings.json. Built for Umbraco v17&#x2B;.]]></description>
                    <pubDate>Thu, 11 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/im.umbraco.ai.local</guid>
                    <title>IM.Umbraco.AI.Local</title>
                    <link>https://marketplace.umbraco.com/package/im.umbraco.ai.local</link>
                    <description><![CDATA[Local LLM provider for Umbraco AI. Connects the Umbraco backoffice AI features (prompts, agents, Copilot, embeddings) to any OpenAI-compatible self-hosted server such as Ollama, LM Studio or vLLM &#x2014; no cloud account required.]]></description>
                    <pubDate>Thu, 11 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/flowcourier.umbraco.cookieconsent</guid>
                    <title>Flowcourier.Umbraco.CookieConsent</title>
                    <link>https://marketplace.umbraco.com/package/flowcourier.umbraco.cookieconsent</link>
                    <description><![CDATA[A comprehensive cookie consent solution for Umbraco CMS with Google Consent Mode v2 support, customizable categories, and statistics tracking.]]></description>
                    <pubDate>Wed, 10 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.forms.automate</guid>
                    <title>Umbraco.Forms.Automate</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.forms.automate</link>
                    <description><![CDATA[Umbraco Forms triggers and actions for Umbraco Automate]]></description>
                    <pubDate>Wed, 10 Jun 2026 00:00:00 Z</pubDate>
                        <category>hq</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.engage.automate</guid>
                    <title>Umbraco.Engage.Automate</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.engage.automate</link>
                    <description><![CDATA[Umbraco Engage triggers and actions for Umbraco Automate]]></description>
                    <pubDate>Wed, 10 Jun 2026 00:00:00 Z</pubDate>
                        <category>hq</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.workflow.automate</guid>
                    <title>Umbraco.Workflow.Automate</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.workflow.automate</link>
                    <description><![CDATA[Umbraco Workflow triggers for Umbraco Automate]]></description>
                    <pubDate>Wed, 10 Jun 2026 00:00:00 Z</pubDate>
                        <category>hq</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.commerce.automate</guid>
                    <title>Umbraco.Commerce.Automate</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.commerce.automate</link>
                    <description><![CDATA[Umbraco Commerce triggers and actions for Umbraco Automate]]></description>
                    <pubDate>Wed, 10 Jun 2026 00:00:00 Z</pubDate>
                        <category>hq</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.ai.automate</guid>
                    <title>Umbraco.AI.Automate</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.ai.automate</link>
                    <description><![CDATA[Umbraco Automate integration for Umbraco.AI.Agent]]></description>
                    <pubDate>Wed, 10 Jun 2026 00:00:00 Z</pubDate>
                        <category>hq</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.ai.search</guid>
                    <title>Umbraco.AI.Search</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.ai.search</link>
                    <description><![CDATA[AI-powered vector search provider for Umbraco CMS]]></description>
                    <pubDate>Wed, 10 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/bt.redirectmanager</guid>
                    <title>BT.RedirectManager</title>
                    <link>https://marketplace.umbraco.com/package/bt.redirectmanager</link>
                    <description><![CDATA[Modern URL redirect manager for Umbraco 13 and 17. Manage 301, 302, 404, and 410 redirects from a clean backoffice dashboard with regex support, CSV import/export, and a built&#x2011;in test tool.]]></description>
                    <pubDate>Wed, 10 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.deploy.automate</guid>
                    <title>Umbraco.Deploy.Automate</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.deploy.automate</link>
                    <description><![CDATA[Umbraco Deploy support for Umbraco Automate (artifacts, service connectors, triggers and actions).]]></description>
                    <pubDate>Wed, 10 Jun 2026 00:00:00 Z</pubDate>
                        <category>hq</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/esatto.umbraco.backoffice.contenttreednd</guid>
                    <title>Esatto.Umbraco.Backoffice.ContentTreeDnd</title>
                    <link>https://marketplace.umbraco.com/package/esatto.umbraco.backoffice.contenttreednd</link>
                    <description><![CDATA[Native HTML5 drag-and-drop for the Umbraco 17 backoffice Content tree. Adds three-zone (above / into / below) drop targets per row with optimistic same-parent reorder and full cross-parent move support. Pure App_Plugins package &#x2014; no C# code.]]></description>
                    <pubDate>Wed, 10 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/crumpled.nostalgid</guid>
                    <title>Crumpled.Nostalgid</title>
                    <link>https://marketplace.umbraco.com/package/crumpled.nostalgid</link>
                    <description><![CDATA[...]]></description>
                    <pubDate>Wed, 10 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://umbraco.com/blog/umbraco-product-updatecodegarden-keynote-highlights-q2-2026/</guid>
                    <title>Umbraco Product Update/Codegarden Keynote Highlights, Q2 2026</title>
                    <link>https://umbraco.com/blog/umbraco-product-updatecodegarden-keynote-highlights-q2-2026/</link>
                    <description><![CDATA[Missed the Codegarden 2026 Keynote? Catch up on Umbraco&#x27;s Q2 product updates, including Umbraco Automate (new product!), CMS Elements, and Load Balancing for Cloud.]]></description>
                    <pubDate>Wed, 10 Jun 2026 00:00:00 Z</pubDate>
                        <category>hq</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://umbraco.com/blog/the-umbraco-mvps-2026/</guid>
                    <title>The Umbraco MVPs 2026</title>
                    <link>https://umbraco.com/blog/the-umbraco-mvps-2026/</link>
                    <description><![CDATA[Meet our Umbraco MVPs for 2026. These are our Most Valuable People, people who have a passion for contributing to Umbraco and the Umbraco Community.]]></description>
                    <pubDate>Wed, 10 Jun 2026 00:00:00 Z</pubDate>
                        <category>hq</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://umbraco.com/blog/umbraco-awards-winners-2026/</guid>
                    <title>Umbraco Awards Winners 2026 &#x1F3C6;</title>
                    <link>https://umbraco.com/blog/umbraco-awards-winners-2026/</link>
                    <description><![CDATA[Umbraco Awards 2026 winners are announced! Discover the outstanding projects and celebrate the amazing work within the Umbraco ecosystem.]]></description>
                    <pubDate>Wed, 10 Jun 2026 00:00:00 Z</pubDate>
                        <category>hq</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.automate</guid>
                    <title>Umbraco.Automate</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.automate</link>
                    <description><![CDATA[Umbraco Automate]]></description>
                    <pubDate>Wed, 10 Jun 2026 00:00:00 Z</pubDate>
                        <category>hq</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://www.dynamicdave.nl/blog/nominated-for-an-umbraco-solution-award/</guid>
                    <title>Nominated for an Umbraco Solution Award</title>
                    <link>https://www.dynamicdave.nl/blog/nominated-for-an-umbraco-solution-award/</link>
                    <description><![CDATA[Feeling incredibly proud to have been nominated for an Umbraco Solution Award this year!]]></description>
                    <pubDate>Tue, 09 Jun 2026 22:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://codeshare.co.uk/blog/how-to-add-giscus-comments-to-an-umbraco-site/</guid>
                    <title>How to add Giscus Comments to an Umbraco Site</title>
                    <link>https://codeshare.co.uk/blog/how-to-add-giscus-comments-to-an-umbraco-site/</link>
                    <description><![CDATA[Add Giscus comments to your Umbraco site with GitHub Discussions. Free, open-source comment system with no backend, privacy-friendly, and developer-native.]]></description>
                    <pubDate>Mon, 08 Jun 2026 01:18:50 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.cms.search.core</guid>
                    <title>Umbraco.Cms.Search.Core</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.cms.search.core</link>
                    <description><![CDATA[Umbraco Search provides an abstraction for search services in Umbraco, allowing for implementations using search providers such as Examine.]]></description>
                    <pubDate>Mon, 08 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://www.enkelmedia.se/blogg/2026/6/7/codegarden-talk-hybrid-cache-changes-everything?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=rss</guid>
                    <title>CodeGarden-talk: Hybrid Cache changes everything</title>
                    <link>https://www.enkelmedia.se/blogg/2026/6/7/codegarden-talk-hybrid-cache-changes-everything?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=rss</link>
                    <description><![CDATA[I recently spent some time looking closer at the new HybridCache implementation in Umbraco to prepare for my presentation at CodeGarden 2026, and the short version is this: it changes more than just the cache layer.&#xA;&#xA;Historically, Umbraco has been very good at keeping published content available in memory. That has made many common developer patterns feel cheap and convenient. Things like traversing content trees, using `.Children()`, `.Descendants()` and resolving references have often just worked without us thinking too much about the cost.&#xA;With HybridCache, that mental model changes. The cache is still there, but not everything necessarily lives in memory all the time.&#xA;The big win is scalability&#xA;The reason for this change is very easy to understand when looking at large Umbraco installations.&#xA;Keeping everything in memory can work beautifully for small and medium-sized sites, but it becomes painful when a site has hundreds of thousands of pages, many languages, or very large content structures. Startup time, memory usage and hosting constraints can become real problems.&#xA;HybridCache helps by reducing the memory footprint and making startup faster. Instead of loading everything into memory, Umbraco can seed important content and load other content when needed. That is a big architectural improvement.&#xA;The cost did not disappear&#xA;The interesting part, at least for me as a developer, is that the cost did not vanish. It moved.&#xA;Some operations that used to feel almost free can now become more expensive, especially on larger sites. Traversing a large tree, filtering over many children, or resolving many references may trigger more cache lookups or database access than before.&#xA;That does not mean HybridCache is bad. Quite the opposite. But it does mean we need to be more intentional about how we build things like menus, listings, sitemaps and search-driven pages.&#xA;&#xA;Use the right tool for the job&#xA;One of my main takeaways is that we should stop treating the published content cache as the answer to everything.&#xA;For search and filtering, Examine is often a much better fit. For menus, footers and repeated structures, runtime cache or prebuilt DTOs can be a good option. For sitemaps, adding the right data to the index (e.g. URLs) can be much more scalable than traversing the whole content tree.&#xA;So the practical message is simple: measure, observe, and choose the right approach based on what the page actually needs to do.&#xA;HybridCache gives Umbraco a better foundation for large sites, but it also makes performance patterns more visible. And honestly, that is probably a good thing.&#xA;Download the slides&#xA;I&#x2019;ve shared the full slide deck from the presentation if you want to dig into the examples, benchmarks and diagrams in more detail.&#xA;Download the slides]]></description>
                    <pubDate>Sun, 07 Jun 2026 05:31:32 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/knowit.umbraco.translationmanager</guid>
                    <title>Knowit.Umbraco.TranslationManager</title>
                    <link>https://marketplace.umbraco.com/package/knowit.umbraco.translationmanager</link>
                    <description><![CDATA[Backoffice dashboard for auditing Umbraco translation dictionary keys against actual code usage. Surfaces unused keys, missing translations, and language coverage gaps across Razor, React, Vue, or any custom pattern. Includes a setup wizard, multi-source scanning, and bulk dictionary management.]]></description>
                    <pubDate>Fri, 05 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/knowit.umbraco.svgpicker</guid>
                    <title>Knowit.Umbraco.SvgPicker</title>
                    <link>https://marketplace.umbraco.com/package/knowit.umbraco.svgpicker</link>
                    <description><![CDATA[Property editor for Umbraco 17 that adds a visual SVG icon picker to the backoffice. Editors browse and search symbols from any configured SVG spritesheet. Stores the symbol ID as a plain string and renders as svg/use in Razor via a built-in Html.SvgIcon() helper.]]></description>
                    <pubDate>Fri, 05 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://joe.gl/ombek/blog/codegarden-packing-list/</guid>
                    <title>Codegarden: What to bring (2026 edition!)</title>
                    <link>https://joe.gl/ombek/blog/codegarden-packing-list/</link>
                    <description><![CDATA[Wow, hasn&#x27;t time flown?! This weekend I&#x27;ll be boarding my plane to Denmark ahead of Codegarden 2026 so it&#x27;s about time we thought about packing our bags! But what to bring? If you&#x27;ve not been before, or if you&#x27;re forgetful like I am, I&#x27;ve written you a packing list...]]></description>
                    <pubDate>Thu, 04 Jun 2026 10:14:30 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://umbraco.com/blog/security-advisory-june-4-2026-security-patch-for-umbracoai-is-now-available/</guid>
                    <title>Umbraco.AI Security Advisory, June 4, 2026</title>
                    <link>https://umbraco.com/blog/security-advisory-june-4-2026-security-patch-for-umbracoai-is-now-available/</link>
                    <description><![CDATA[Security patches are available for Umbraco.AI core package, versions 1.0.0 through 1.13.x versions fix a moderate vulnerability. Find the fix here]]></description>
                    <pubDate>Thu, 04 Jun 2026 00:00:00 Z</pubDate>
                        <category>hq</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://uskinned.net/blog/all-starter-kit-and-theme-add-ons-are-now-available-for-umbraco-17/</guid>
                    <title>All uSkinned Starter Kit and Themes Add-ons Out for Umbraco 17</title>
                    <link>https://uskinned.net/blog/all-starter-kit-and-theme-add-ons-are-now-available-for-umbraco-17/</link>
                    <description><![CDATA[All Starter Kit and Themes Add-ons Out for Umbraco 17&#xA;Every uSkinned Starter Kit and Theme add-on is now ready for Umbraco 17 and uSkinned Site Builder 7.]]></description>
                    <pubDate>Wed, 03 Jun 2026 09:42:08 Z</pubDate>
                        <category>blog</category>
                        <category>community</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.markup</guid>
                    <title>SplatDev.Umbraco.Markup</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.markup</link>
                    <description><![CDATA[HTML/markup helpers and extensions for Umbraco 13 (net8.0) and Umbraco 17 (net10.0)]]></description>
                    <pubDate>Wed, 03 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.charlimit</guid>
                    <title>SplatDev.Umbraco.Plugins.CharLimit</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.charlimit</link>
                    <description><![CDATA[Character limit property editor for Umbraco &#x2014; enforces max length on text properties with live counter display.]]></description>
                    <pubDate>Wed, 03 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.rdpmanager</guid>
                    <title>SplatDev.Umbraco.Plugins.RdpManager</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.rdpmanager</link>
                    <description><![CDATA[Umbraco Remote Desktop connection manager plugin &#x2014; store RDP configs and generate .rdp file downloads. Supports Umbraco 13 (net8.0) and Umbraco 17 (net10.0)]]></description>
                    <pubDate>Wed, 03 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.countries</guid>
                    <title>SplatDev.Umbraco.Plugins.Countries</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.countries</link>
                    <description><![CDATA[Umbraco countries data plugin supporting Umbraco 13 (net8.0) and Umbraco 17 (net10.0)]]></description>
                    <pubDate>Wed, 03 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/blendinteractive.umbraco.securitydashboard</guid>
                    <title>BlendInteractive.Umbraco.SecurityDashboard</title>
                    <link>https://marketplace.umbraco.com/package/blendinteractive.umbraco.securitydashboard</link>
                    <description><![CDATA[The Umbraco Security Dashboard is a package that provides a dashboard within the Umbraco backoffice to help identify potential security vulnerabilities in installed packages. It scans installed packages against known vulnerabilities and can report vulnerabilities to a central location via webhook.]]></description>
                    <pubDate>Wed, 03 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.customlogin</guid>
                    <title>SplatDev.Umbraco.Plugins.CustomLogin</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.customlogin</link>
                    <description><![CDATA[Umbraco custom login page plugin with branding support, SSO integration hooks and 2FA readiness. Supports Umbraco 13 (net8.0) and Umbraco 17 (net10.0).]]></description>
                    <pubDate>Wed, 03 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.examineextensions</guid>
                    <title>SplatDev.Umbraco.Plugins.ExamineExtensions</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.examineextensions</link>
                    <description><![CDATA[Examine search extensions for Umbraco &#x2014; additional query helpers, result transformers, and index utilities.]]></description>
                    <pubDate>Wed, 03 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.seo</guid>
                    <title>SplatDev.Umbraco.Plugins.SEO</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.seo</link>
                    <description><![CDATA[Umbraco SEO plugin supporting Umbraco 13 (net8.0) and Umbraco 17 (net10.0)]]></description>
                    <pubDate>Wed, 03 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.slider</guid>
                    <title>SplatDev.Umbraco.Plugins.Slider</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.slider</link>
                    <description><![CDATA[Image slider plugin for Umbraco &#x2014; stores slide data with EF Core, renders via configurable view component.]]></description>
                    <pubDate>Wed, 03 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.memberlogin</guid>
                    <title>SplatDev.Umbraco.Plugins.MemberLogin</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.memberlogin</link>
                    <description><![CDATA[Custom member login for Umbraco: login form, remember me, forgot password, lockout handling. Supports Umbraco 13 (net8.0) and Umbraco 17 (net10.0).]]></description>
                    <pubDate>Wed, 03 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.membertypes</guid>
                    <title>SplatDev.Umbraco.Plugins.MemberTypes</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.membertypes</link>
                    <description><![CDATA[Umbraco Member Type management plugin: create/edit custom member types with profile fields, custom properties and type templates. Supports Umbraco 13 (net8.0) and Umbraco 17 (net10.0).]]></description>
                    <pubDate>Wed, 03 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.socialmedia.share</guid>
                    <title>SplatDev.Umbraco.Plugins.SocialMedia.Share</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.socialmedia.share</link>
                    <description><![CDATA[Umbraco social sharing buttons plugin &#x2014; configurable platforms and share links. Supports Umbraco 13 (net8.0) and Umbraco 17 (net10.0)]]></description>
                    <pubDate>Wed, 03 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.tweets</guid>
                    <title>SplatDev.Umbraco.Plugins.Tweets</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.tweets</link>
                    <description><![CDATA[Twitter/X feed display plugin for Umbraco 13 (net8.0) and Umbraco 17 (net10.0). Caches tweets locally and refreshes on a configurable schedule.]]></description>
                    <pubDate>Wed, 03 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.visitorcounter</guid>
                    <title>SplatDev.Umbraco.Plugins.VisitorCounter</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.visitorcounter</link>
                    <description><![CDATA[Umbraco visitor counter plugin: tracks unique and total site visitors, provides daily counts and a display widget. Supports Umbraco 13 (net8.0) and Umbraco 17 (net10.0).]]></description>
                    <pubDate>Wed, 03 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.surveys</guid>
                    <title>SplatDev.Umbraco.Plugins.Surveys</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.surveys</link>
                    <description><![CDATA[Umbraco survey builder plugin with questions, multiple choice, free text, rating, and results dashboard. Supports Umbraco 13 (net8.0) and Umbraco 17 (net10.0).]]></description>
                    <pubDate>Wed, 03 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.wordsapi</guid>
                    <title>SplatDev.Umbraco.Plugins.WordsApi</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.wordsapi</link>
                    <description><![CDATA[Umbraco Words API plugin supporting Umbraco 13 (net8.0) and Umbraco 17 (net10.0)]]></description>
                    <pubDate>Wed, 03 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.newsticker</guid>
                    <title>SplatDev.Umbraco.Plugins.NewsTicker</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.newsticker</link>
                    <description><![CDATA[Scrolling news ticker plugin for Umbraco 13 (net8.0) and Umbraco 17 (net10.0). Configurable items, speed, and direction stored in the database.]]></description>
                    <pubDate>Wed, 03 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.exceptionmanager</guid>
                    <title>SplatDev.Umbraco.Plugins.ExceptionManager</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.exceptionmanager</link>
                    <description><![CDATA[Umbraco exception handling middleware plugin supporting Umbraco 13 (net8.0) and Umbraco 17 (net10.0)]]></description>
                    <pubDate>Wed, 03 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.newsletters</guid>
                    <title>SplatDev.Umbraco.Plugins.Newsletters</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.newsletters</link>
                    <description><![CDATA[Newsletter subscriber management, campaigns, and send tracking for Umbraco 13 (net8.0) and Umbraco 17 (net10.0).]]></description>
                    <pubDate>Wed, 03 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.rsvp</guid>
                    <title>SplatDev.Umbraco.Plugins.Rsvp</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.rsvp</link>
                    <description><![CDATA[Umbraco RSVP event registration plugin with attendee management, capacity limits, waitlisting, and cancellation support. Supports Umbraco 13 (net8.0) and Umbraco 17 (net10.0).]]></description>
                    <pubDate>Wed, 03 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.ispservices</guid>
                    <title>SplatDev.Umbraco.Plugins.IspServices</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.ispservices</link>
                    <description><![CDATA[Umbraco ISP/IP services utilities plugin supporting Umbraco 13 (net8.0) and Umbraco 17 (net10.0)]]></description>
                    <pubDate>Wed, 03 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://www.jeroenbreuer.nl/blog/umbraco-openid-connect-example-with-lightweight-external-members/</guid>
                    <title>Umbraco OpenID Connect example with lightweight external members</title>
                    <link>https://www.jeroenbreuer.nl/blog/umbraco-openid-connect-example-with-lightweight-external-members/</link>
                    <description><![CDATA[The Umbraco OpenID Connect example has been updated to Umbraco 17.4.2 with support for lightweight external members . This stores members from an external provider as a minimal record instead of a full content entity.]]></description>
                    <pubDate>Tue, 02 Jun 2026 17:37:28 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://owain.codes/blog/2026/june/speed-up-slow-deployments-to-umbraco-cloud/</guid>
                    <title>Speed up slow deployments to Umbraco Cloud</title>
                    <link>https://owain.codes/blog/2026/june/speed-up-slow-deployments-to-umbraco-cloud/</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Tue, 02 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.payments.mercadopago</guid>
                    <title>SplatDev.Umbraco.Plugins.Payments.MercadoPago</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.payments.mercadopago</link>
                    <description><![CDATA[MercadoPago payment integration for Umbraco. Supports preference creation, payment status lookup, and webhook handling. Supports Umbraco 13 (net8.0) and Umbraco 17 (net10.0).]]></description>
                    <pubDate>Tue, 02 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.d4sign</guid>
                    <title>SplatDev.Umbraco.Plugins.D4Sign</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.d4sign</link>
                    <description><![CDATA[D4Sign digital signature integration for Umbraco. Supports document upload, signer management, webhook processing, and a Lit 3 backoffice dashboard. Supports Umbraco 13 (net8.0) and Umbraco 17 (net10.0).]]></description>
                    <pubDate>Tue, 02 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.videopreview</guid>
                    <title>SplatDev.Umbraco.Plugins.VideoPreview</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.videopreview</link>
                    <description><![CDATA[Video thumbnail preview for Umbraco &#x2014; auto-generate thumbnail URLs from YouTube, Vimeo, and Dailymotion video URLs. Supports Umbraco 13 (net8.0) and Umbraco 17 (net10.0).]]></description>
                    <pubDate>Tue, 02 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.adminbar</guid>
                    <title>SplatDev.Umbraco.Plugins.AdminBar</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.adminbar</link>
                    <description><![CDATA[Fixed admin bar injected at the top of the page for logged-in backoffice users. Provides Edit Page, Preview and Publish shortcuts. Supports Umbraco 13 (net8.0) and Umbraco 17 (net10.0).]]></description>
                    <pubDate>Tue, 02 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.newsletter</guid>
                    <title>SplatDev.Umbraco.Plugins.Newsletter</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.newsletter</link>
                    <description><![CDATA[Newsletter subscriber lists, campaigns, Mailgun bulk send, and stats tracking for Umbraco 17 (net10.0). Depends on SplatDev.Umbraco.Plugins.EmailTemplates for rendering.]]></description>
                    <pubDate>Tue, 02 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.livevideo</guid>
                    <title>SplatDev.Umbraco.Plugins.LiveVideo</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.livevideo</link>
                    <description><![CDATA[Live video embed for Umbraco &#x2014; YouTube Live, Twitch, and Vimeo live stream integration. Supports Umbraco 13 (net8.0) and Umbraco 17 (net10.0).]]></description>
                    <pubDate>Tue, 02 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/uskinnedsitebuilder.starterkit.thefoundry</guid>
                    <title>uSkinnedSiteBuilder.StarterKit.TheFoundry</title>
                    <link>https://marketplace.umbraco.com/package/uskinnedsitebuilder.starterkit.thefoundry</link>
                    <description><![CDATA[The Foundry Starter Kit for uSkinned Site Builder for Umbraco CMS]]></description>
                    <pubDate>Tue, 02 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.payments.pagseguro</guid>
                    <title>SplatDev.Umbraco.Plugins.Payments.PagSeguro</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.payments.pagseguro</link>
                    <description><![CDATA[PagSeguro payment integration for Umbraco. Supports checkout session creation, transaction status lookup. Supports Umbraco 13 (net8.0) and Umbraco 17 (net10.0).]]></description>
                    <pubDate>Tue, 02 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.gdrp</guid>
                    <title>SplatDev.Umbraco.Plugins.Gdrp</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.gdrp</link>
                    <description><![CDATA[GDPR compliance plugin for Umbraco &#x2014; cookie consent banner, data export, and right to erasure requests. Supports Umbraco 13 (net8.0) and Umbraco 17 (net10.0).]]></description>
                    <pubDate>Tue, 02 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.enotassina</guid>
                    <title>SplatDev.Umbraco.Plugins.ENotAssina</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.enotassina</link>
                    <description><![CDATA[e-Not Assina electronic signature integration for Umbraco. Supports document creation, sequential signing, webhook processing, PDF download, and a Lit 3 backoffice dashboard. Supports Umbraco 13 (net8.0) and Umbraco 17 (net10.0).]]></description>
                    <pubDate>Tue, 02 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.payments.bancointer</guid>
                    <title>SplatDev.Umbraco.Plugins.Payments.BancoInter</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.payments.bancointer</link>
                    <description><![CDATA[Banco Inter payment integration for Umbraco. Supports Pix (immediate and due charges), Boleto com Pix, Banking (outbound Pix, boleto payments, balance/statement), and webhook handling. Supports Umbraco 13 (net8.0) and Umbraco 17 (net10.0).]]></description>
                    <pubDate>Tue, 02 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://33b6c16b-3387-4d68-9090-4cb1f20ea7b3.azurewebsites.nethttps://owain.codes/blog/2026/june/speed-up-slow-deployments-to-umbraco-cloud/</guid>
                    <title>Speed up slow deployments to Umbraco Cloud</title>
                    <link>https://33b6c16b-3387-4d68-9090-4cb1f20ea7b3.azurewebsites.nethttps://owain.codes/blog/2026/june/speed-up-slow-deployments-to-umbraco-cloud/</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Tue, 02 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.dictionarymanager</guid>
                    <title>SplatDev.Umbraco.Plugins.DictionaryManager</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.dictionarymanager</link>
                    <description><![CDATA[Dictionary import/export/CRUD manager for Umbraco &#x2014; full rewrite of the Umbraco 8 plugin using ILocalizationService. Supports Umbraco 13 (net8.0) and Umbraco 17 (net10.0).]]></description>
                    <pubDate>Tue, 02 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://skrift.io/issues/#128</guid>
                    <title>Skrift Issue #128</title>
                    <link>https://skrift.io/issues/#128</link>
                    <description><![CDATA[Featuring guest posts by Pasang Tamang on &quot;From Umbraco 8 to Umbraco 17 in One Leap: uSync, Cursor, and the Umbraco MCP&quot; and Aaron Sawyer on &quot;Using Local LLMs wth Umbraco MCP&quot;]]></description>
                    <pubDate>Tue, 02 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                        <category>skrift</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.hiddencontent</guid>
                    <title>SplatDev.Umbraco.Plugins.HiddenContent</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.hiddencontent</link>
                    <description><![CDATA[Umbraco Hidden Content plugin: hide nodes from navigation and sitemaps while keeping them accessible by URL via the umbracoNaviHide property. Supports Umbraco 13 (net8.0) and Umbraco 17 (net10.0).]]></description>
                    <pubDate>Tue, 02 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.mailer</guid>
                    <title>SplatDev.Umbraco.Plugins.Mailer</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.mailer</link>
                    <description><![CDATA[Umbraco mailer plugin supporting Umbraco 13 (net8.0) and Umbraco 17 (net10.0)]]></description>
                    <pubDate>Tue, 02 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://owaincodes.uksouth01.umbraco.io/blog/2026/june/speed-up-slow-deployments-to-umbraco-cloud/</guid>
                    <title>Speed up slow deployments to Umbraco Cloud</title>
                    <link>https://owaincodes.uksouth01.umbraco.io/blog/2026/june/speed-up-slow-deployments-to-umbraco-cloud/</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Tue, 02 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.passwordsettings</guid>
                    <title>SplatDev.Umbraco.Plugins.PasswordSettings</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.passwordsettings</link>
                    <description><![CDATA[Umbraco Password Settings plugin: complexity rules, expiration, history (prevent reuse), strength meter. Supports Umbraco 13 (net8.0) and Umbraco 17 (net10.0).]]></description>
                    <pubDate>Tue, 02 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.emailnotifications</guid>
                    <title>SplatDev.Umbraco.Plugins.EmailNotifications</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.emailnotifications</link>
                    <description><![CDATA[Email template engine, Mailgun mail provider, newsletter campaigns, and member notifications for Umbraco 13 (net8.0) and Umbraco 17 (net10.0).]]></description>
                    <pubDate>Tue, 02 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.restricted</guid>
                    <title>SplatDev.Umbraco.Plugins.Restricted</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.restricted</link>
                    <description><![CDATA[Umbraco Restricted Content plugin: member-only content gates, role-based access and paywall support using IPublicAccessService. Supports Umbraco 13 (net8.0) and Umbraco 17 (net10.0).]]></description>
                    <pubDate>Tue, 02 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://www.dynamicdave.nl/blog/why-2026-is-finally-the-year-i-m-going-to-codegarden/</guid>
                    <title>Why 2026 Is Finally the Year I&#x27;m Going to Codegarden</title>
                    <link>https://www.dynamicdave.nl/blog/why-2026-is-finally-the-year-i-m-going-to-codegarden/</link>
                    <description><![CDATA[Some things just hang around on your bucket list forever. You tell yourself, &#x201C;maybe next year,&#x201D; but you never actually get around to it. For me, that&#x2019;s always been Codegarden.I&#x2019;ve been working with Umbraco since version 4&#x2014;so, we&#x2019;re talking 2012 or 2013. That&#x2019;s over a decade of projects, bug fixes, and late-night &#x201C;why is this still broken?&#x201D; moments. But I&#x2019;ve never packed a bag and headed to Copenhagen for the biggest Umbraco event on the planet. Not once. Until now.]]></description>
                    <pubDate>Mon, 01 Jun 2026 22:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://kjac.dev/posts/in-memory-umbraco-search/</guid>
                    <title>In-memory Umbraco Search</title>
                    <link>https://kjac.dev/posts/in-memory-umbraco-search/</link>
                    <description><![CDATA[How to run Umbraco Search purely in-memory.]]></description>
                    <pubDate>Mon, 01 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://33b6c16b-3387-4d68-9090-4cb1f20ea7b3.azurewebsites.nethttps://owain.codes/blog/2026/june/fixing-the-sort-order-in-content-pickers-in-umbraco/</guid>
                    <title>Fixing the sort order in Content Pickers in Umbraco</title>
                    <link>https://33b6c16b-3387-4d68-9090-4cb1f20ea7b3.azurewebsites.nethttps://owain.codes/blog/2026/june/fixing-the-sort-order-in-content-pickers-in-umbraco/</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Mon, 01 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/fastgooey.umbracoforms</guid>
                    <title>FastGooey.UmbracoForms</title>
                    <link>https://marketplace.umbraco.com/package/fastgooey.umbracoforms</link>
                    <description><![CDATA[Render Umbraco Forms into native iOS, macOS and Flutter viewing surfaces directly from your Umbraco projects.]]></description>
                    <pubDate>Mon, 01 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://owaincodes.uksouth01.umbraco.io/blog/2026/june/fixing-the-sort-order-in-content-pickers-in-umbraco/</guid>
                    <title>Fixing the sort order in Content Pickers in Umbraco</title>
                    <link>https://owaincodes.uksouth01.umbraco.io/blog/2026/june/fixing-the-sort-order-in-content-pickers-in-umbraco/</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Mon, 01 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://umbraco.com/blog/more-visibility-more-control-whats-new-in-umbraco-cloud/</guid>
                    <title>More Visibility, More Control. What&#x27;s New in Umbraco Cloud</title>
                    <link>https://umbraco.com/blog/more-visibility-more-control-whats-new-in-umbraco-cloud/</link>
                    <description><![CDATA[Discover what&#x2019;s new and coming next in Umbraco Cloud. Explore new features like performance insights, security updates, and dedicated scaling for agencies.]]></description>
                    <pubDate>Mon, 01 Jun 2026 00:00:00 Z</pubDate>
                        <category>hq</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://owain.codes/blog/2026/june/fixing-the-sort-order-in-content-pickers-in-umbraco/</guid>
                    <title>Fixing the sort order in Content Pickers in Umbraco</title>
                    <link>https://owain.codes/blog/2026/june/fixing-the-sort-order-in-content-pickers-in-umbraco/</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Mon, 01 Jun 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://www.youtube.com/watch?v=cCqq76ItuB4</guid>
                    <title>umbraCoffee - Agents, Codegarden, Tees</title>
                    <link>https://www.youtube.com/watch?v=cCqq76ItuB4</link>
                    <description><![CDATA[Welcome to your monthly dose of #umbraCoffee&#x200B;&#x200B;&#x200B;&#x200B;&#x200B;&#x200B;&#x200B;&#x200B;&#x200B;&#x200B;&#x200B;&#x200B;! Your hosts - Marcin and Callum - together with their guest(s) will drive through all of the community news and happenings in the Umbraco world. So... grab a cuppa, join us LIVE and enjoy!&#xA;&#xA;Today we&#x27;re joined by Adam Shallcross, CEO &amp; Founder of Cogworks &#x2013; and curator oft the Human Vibe Loop newsletter.&#xA;&#xA;See ya?!&#xA;&#xA;---&#xA;&#x2615; Wanna buy us a coffee/pizza/donuts?&#xA;https://www.buymeacoffee.com/umbracoffee&#xA;---&#xA;&#xA;Notes:&#xA;&#xA;- Skrift: https://skrift.io/issues/?utm_source=umbfyi&amp;utm_medium=web#127&#xA;- https://umbraad.com/&#xA;- Bootstrap 3 bye bye from Forms: https://github.com/umbraco/Announcements/issues/35&#xA;- AI Agents everywhere&#x2026;&#xA;- https://codeshare.co.uk/blog/designing-an-ai-agent-skill-for-adding-a-page-type-to-umbraco/&#xA;- Adam&#x2019;s demo? https://marketplace.umbraco.com/package/agentrun.umbraco&#xA;- AI search: https://examinex.online/2026/04/16/ai-semantic-ranking-for-azure-search&#xA;- Logs in Kudu: https://skttl.dev/blog/browsing-umbraco-logs-in-kudu/&#xA;- Personalisation: https://kjac.dev/posts/personalisation-groups-as-segments/&#xA;- Search future: https://www.youtube.com/watch?v=wwQBvBDGhPE&#xA;- Events: https://umbraco.com/events/]]></description>
                    <pubDate>Sat, 30 May 2026 00:06:57 Z</pubDate>
                        <category>community</category>
                        <category>youtube</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.ai.reframe</guid>
                    <title>Umbraco.Community.AI.Reframe</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.ai.reframe</link>
                    <description><![CDATA[Reframe image media to a new aspect ratio without leaving the Umbraco backoffice. A Reframe view on every Image media item lets editors retarget a picture either by Crop (instant, free, geometric) or by AI Outpaint (OpenAI gpt-image-2 invents the new edges so no content is lost). Preview before/after, then Accept to save the result as a new media item &#x2014; the original is never changed. Outpaint requires your own OpenAI API key and incurs OpenAI usage cost; Crop is free.]]></description>
                    <pubDate>Sat, 30 May 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://medium.com/@nomansiddiquins1/sso-in-umbraco-17-azure-ad-back-office-login-with-openid-connect-549a0e5f91e5?source=rss-419ff102baa5------2</guid>
                    <title>SSO in Umbraco 17: Azure AD Back Office Login with OpenID Connect</title>
                    <link>https://medium.com/@nomansiddiquins1/sso-in-umbraco-17-azure-ad-back-office-login-with-openid-connect-549a0e5f91e5?source=rss-419ff102baa5------2</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Fri, 29 May 2026 18:47:06 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://medium.com/@nomansiddiquins1/sso-in-umbraco-17-azure-ad-back-office-login-with-openid-connect-549a0e5f91e5?source=rss------umbraco-5</guid>
                    <title>SSO in Umbraco 17: Azure AD Back Office Login with OpenID Connect</title>
                    <link>https://medium.com/@nomansiddiquins1/sso-in-umbraco-17-azure-ad-back-office-login-with-openid-connect-549a0e5f91e5?source=rss------umbraco-5</link>
                    <description><![CDATA[&lt;div class=&quot;medium-feed-item&quot;&gt;&lt;p class=&quot;medium-feed-image&quot;&gt;&lt;a href=&quot;https://medium.com/@nomansiddiquins1/sso-in-umbraco-17-azure-ad-back-office-login-with-openid-connect-549a0e5f91e5?source=rss------umbraco-5&quot;&gt;&lt;img src=&quot;https://cdn-images-1.medium.com/max/672/1*WGXVMKwKTrCDMQum52uvww.png&quot; width=&quot;672&quot;&gt;&lt;/a&gt;&lt;/p&gt;&lt;p class=&quot;medium-feed-snippet&quot;&gt;A step-by-step guide to wiring up Azure Active Directory as an external login provider for the Umbraco back office &amp;#x2014; with auto-linking&amp;#x2026;&lt;/p&gt;&lt;p class=&quot;medium-feed-link&quot;&gt;&lt;a href=&quot;https://medium.com/@nomansiddiquins1/sso-in-umbraco-17-azure-ad-back-office-login-with-openid-connect-549a0e5f91e5?source=rss------umbraco-5&quot;&gt;Continue reading on Medium &#xBB;&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;]]></description>
                    <pubDate>Fri, 29 May 2026 18:47:06 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://medium.com/@nomansiddiquins1/integrating-amazon-s3-media-storage-hashicorp-vault-secrets-into-umbraco-v17-c2a36410b0a2?source=rss-419ff102baa5------2</guid>
                    <title>Integrating Amazon S3 Media Storage &amp; HashiCorp Vault Secrets into Umbraco v17</title>
                    <link>https://medium.com/@nomansiddiquins1/integrating-amazon-s3-media-storage-hashicorp-vault-secrets-into-umbraco-v17-c2a36410b0a2?source=rss-419ff102baa5------2</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Fri, 29 May 2026 13:45:02 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://www.jeroenbreuer.nl/blog/umbraco-mvp-2026/</guid>
                    <title>Umbraco MVP 2026!</title>
                    <link>https://www.jeroenbreuer.nl/blog/umbraco-mvp-2026/</link>
                    <description><![CDATA[Woohoo! Proud to receive my seventh Umbraco MVP award in 2026, marking another year of sharing, building, and community-driven progress.]]></description>
                    <pubDate>Fri, 29 May 2026 11:41:10 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://umbracocommunity.social/@lee/116654381716004252</guid>
                    <title>Contentment 7.0.0-alpha001 for Umbraco 18 RC out now</title>
                    <link>https://umbracocommunity.social/@lee/116654381716004252</link>
                    <description><![CDATA[#umbraco #Contentment 7.0.0-alpha001https://github.com/leekelleher/umbraco-contentment/releases/tag/7.0.0-alpha001TL;DR, want to try out Umbraco 18 with Contentment this weekend?Is it stable? Probably!Does it have bugs? Nah!How can you help? Test it out and feedback!]]></description>
                    <pubDate>Fri, 29 May 2026 06:23:49 Z</pubDate>
                        <category>community</category>
                        <category>social</category>
                        <category>mastodon</category>
                </item>
                <item>
                    <guid>https://medium.com/@ravimotha/codegarden26-a-guide-1ad134dad6b1?source=rss-8e76be83b03f------2</guid>
                    <title>CodeGarden26 : a guide</title>
                    <link>https://medium.com/@ravimotha/codegarden26-a-guide-1ad134dad6b1?source=rss-8e76be83b03f------2</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Thu, 28 May 2026 16:53:23 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://umbracocommunity.social/@owaincodes/116652325620551265</guid>
                    <title>Umbraco Forums #h5yr now display on HFYR.com</title>
                    <link>https://umbracocommunity.social/@owaincodes/116652325620551265</link>
                    <description><![CDATA[Pleased to announce that now, if you give a #h5yr on the Umbraco Forum, that post will be displayed on H5YR.com Thanks @sebastiaan for helping get this setup. #umbraco]]></description>
                    <pubDate>Thu, 28 May 2026 13:00:42 Z</pubDate>
                        <category>community</category>
                        <category>social</category>
                        <category>mastodon</category>
                </item>
                <item>
                    <guid>https://umbracocommunity.social/@UmbHost/116651510454937905</guid>
                    <title>UmbHost launches automated Umbraco upgrades</title>
                    <link>https://umbracocommunity.social/@UmbHost/116651510454937905</link>
                    <description><![CDATA[Automated Umbraco upgrades, sorted. GitHub Dependabot handles the dependency PRs, GreenStack handles the deploy. Here&#x27;s how you can do it &#x1F447;https://umbhost.net/blog/2026/05/building-your-own-umbraco-cloud-style-auto-upgrades-with-github-dependabot#Umbraco #dotnet #DevOps #GreenStack]]></description>
                    <pubDate>Thu, 28 May 2026 09:35:45 Z</pubDate>
                        <category>community</category>
                        <category>social</category>
                        <category>mastodon</category>
                </item>
                <item>
                    <guid>https://umbraco.com/blog/umbraco-18-release-candidate/</guid>
                    <title>Umbraco 18 Release Candidate</title>
                    <link>https://umbraco.com/blog/umbraco-18-release-candidate/</link>
                    <description><![CDATA[Discover and test the Umbraco 18 Release Candidate, featuring Elements for reusable content, typed OpenAPI schemas,]]></description>
                    <pubDate>Thu, 28 May 2026 00:00:00 Z</pubDate>
                        <category>hq</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://www.nevitech.co.uk/blog/noisy-imagesharp-logs-in-umbraco/</guid>
                    <title>Noisy ImageSharp Logs in Umbraco</title>
                    <link>https://www.nevitech.co.uk/blog/noisy-imagesharp-logs-in-umbraco/</link>
                    <description><![CDATA[ImageSharp logs every image request at INFO level, quietly filling your Umbraco logs until the backoffice viewer hits its 100 MB limit and refuses to open them. Here&#x27;s the one line Serilog fix, plus why a CDN helps.]]></description>
                    <pubDate>Wed, 27 May 2026 23:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://www.jeroenbreuer.nl/blog/how-i-let-cursor-build-an-azure-search-provider-for-umbraco-search/</guid>
                    <title>How I let Cursor build an Azure Search provider for Umbraco Search</title>
                    <link>https://www.jeroenbreuer.nl/blog/how-i-let-cursor-build-an-azure-search-provider-for-umbraco-search/</link>
                    <description><![CDATA[I wanted to build an Azure Search provider for Umbraco and let Cursor do the heavy lifting. This is what that looked like from the first prompt to the final commit.]]></description>
                    <pubDate>Wed, 27 May 2026 09:21:27 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://owain.codes/blog/2026/may/codegarden-2026-not-long-now/</guid>
                    <title>Codegarden 2026 - not long now!</title>
                    <link>https://owain.codes/blog/2026/may/codegarden-2026-not-long-now/</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Wed, 27 May 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://owaincodes.uksouth01.umbraco.io/blog/2026/may/codegarden-2026-not-long-now/</guid>
                    <title>Codegarden 2026 - not long now!</title>
                    <link>https://owaincodes.uksouth01.umbraco.io/blog/2026/may/codegarden-2026-not-long-now/</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Wed, 27 May 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://33b6c16b-3387-4d68-9090-4cb1f20ea7b3.azurewebsites.nethttps://owain.codes/blog/2026/may/codegarden-2026-not-long-now/</guid>
                    <title>Codegarden 2026 - not long now!</title>
                    <link>https://33b6c16b-3387-4d68-9090-4cb1f20ea7b3.azurewebsites.nethttps://owain.codes/blog/2026/may/codegarden-2026-not-long-now/</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Wed, 27 May 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/lantern.umbraco</guid>
                    <title>Lantern.Umbraco</title>
                    <link>https://marketplace.umbraco.com/package/lantern.umbraco</link>
                    <description><![CDATA[Add the Lantern bug-tracking widget to every page of your Umbraco site in seconds. Configure your embed key from the backoffice &#x2014; no template changes needed.]]></description>
                    <pubDate>Wed, 27 May 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://medium.com/@contacts_81271/umbraco-vs-wordpress-b180bf6af576?source=rss------umbraco-5</guid>
                    <title>Umbraco vs WordPress</title>
                    <link>https://medium.com/@contacts_81271/umbraco-vs-wordpress-b180bf6af576?source=rss------umbraco-5</link>
                    <description><![CDATA[&lt;div class=&quot;medium-feed-item&quot;&gt;&lt;p class=&quot;medium-feed-image&quot;&gt;&lt;a href=&quot;https://medium.com/@contacts_81271/umbraco-vs-wordpress-b180bf6af576?source=rss------umbraco-5&quot;&gt;&lt;img src=&quot;https://cdn-images-1.medium.com/max/1672/1*rTkBaNhm67woupfcRsK7FA.png&quot; width=&quot;1672&quot;&gt;&lt;/a&gt;&lt;/p&gt;&lt;p class=&quot;medium-feed-snippet&quot;&gt;Die Wahl des richtigen Web-Content-Management-Systems gleicht heute einer strategischen Richtungsentscheidung, die ma&amp;#xDF;geblichen Einfluss&amp;#x2026;&lt;/p&gt;&lt;p class=&quot;medium-feed-link&quot;&gt;&lt;a href=&quot;https://medium.com/@contacts_81271/umbraco-vs-wordpress-b180bf6af576?source=rss------umbraco-5&quot;&gt;Continue reading on Medium &#xBB;&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;]]></description>
                    <pubDate>Tue, 26 May 2026 10:17:32 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://skttl.dev/blog/browsing-umbraco-logs-in-kudu/</guid>
                    <title>Browsing Umbraco Logs in Kudu</title>
                    <link>https://skttl.dev/blog/browsing-umbraco-logs-in-kudu/</link>
                    <description><![CDATA[A new userscript that brings a proper Serilog log viewer into the Kudu interface: file picker, expression search, saved queries, and a momentum graph, all with no build step required.]]></description>
                    <pubDate>Tue, 26 May 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/upreviewshare</guid>
                    <title>uPreviewShare</title>
                    <link>https://marketplace.umbraco.com/package/upreviewshare</link>
                    <description><![CDATA[Securely share unpublished draft content with external stakeholders via time-limited, view-capped, and PIN-protected preview links. Renders through actual Umbraco templates.]]></description>
                    <pubDate>Tue, 26 May 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://github.com/skybrud/Skybrud.Umbraco.Redirects.Automate/releases/tag/v17.0.0-alpha001</guid>
                    <title>Skybrud.Umbraco.Redirects.Automate 17.0.0-alpha001</title>
                    <link>https://github.com/skybrud/Skybrud.Umbraco.Redirects.Automate/releases/tag/v17.0.0-alpha001</link>
                    <description><![CDATA[Automate addon for Skybrud Redirects.]]></description>
                    <pubDate>Mon, 25 May 2026 20:37:50 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                </item>
                <item>
                    <guid>https://github.com/skybrud/Skybrud.Umbraco.Redirects/releases/tag/v17.0.5</guid>
                    <title>Skybrud.Umbraco.Redirects 17.0.5</title>
                    <link>https://github.com/skybrud/Skybrud.Umbraco.Redirects/releases/tag/v17.0.5</link>
                    <description><![CDATA[Award winning redirects manager for Umbraco.]]></description>
                    <pubDate>Mon, 25 May 2026 20:08:42 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                </item>
                <item>
                    <guid>https://anju-dev-notes.hashnode.dev/azure-key-vault-configuration-using-rbac-in-azure-app-service</guid>
                    <title>Azure Key Vault Configuration Using RBAC in Azure App Service</title>
                    <link>https://anju-dev-notes.hashnode.dev/azure-key-vault-configuration-using-rbac-in-azure-app-service</link>
                    <description><![CDATA[Managing secrets securely is one of the most important aspects of modern cloud applications. Instead of storing sensitive values like connection strings, API keys, or passwords directly inside applica]]></description>
                    <pubDate>Mon, 25 May 2026 11:51:18 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://www.youtube.com/watch?v=wwQBvBDGhPE</guid>
                    <title>Umbraco Search Explained | Kenn Jacobsen | Umbraco India Meetup</title>
                    <link>https://www.youtube.com/watch?v=wwQBvBDGhPE</link>
                    <description><![CDATA[Featuring Kenn Jacobsen&#xA;Kenn is a 4x Umbraco MVP and a long-time contributor to the Umbraco community, with more than 10 years of experience building solutions with Umbraco and .NET.&#xA;&#xA;&#x1F4FA; Watch the full session recording and learn what&#x2019;s coming next for search in the Umbraco ecosystem.&#xA;&#xA;&#x1F30D; Join us for upcoming Umbraco India User Group events and community updates.&#xA;&#x1F517;https://www.meetup.com/umbraco-india-user-group&#xA;&#x1F517;https://www.linkedin.com/groups/14558029]]></description>
                    <pubDate>Thu, 21 May 2026 09:52:54 Z</pubDate>
                        <category>community</category>
                        <category>youtube</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/m1sterpl0w.umbraco.accessrestriction</guid>
                    <title>M1sterPl0w.Umbraco.AccessRestriction</title>
                    <link>https://marketplace.umbraco.com/package/m1sterpl0w.umbraco.accessrestriction</link>
                    <description><![CDATA[An Umbraco package that restricts access to your site (or specific paths) by IP address whitelist. Manage whitelisted IPs and restricted paths from a dashboard in the Umbraco backoffice, with optional hardcoded entries via appsettings.json.]]></description>
                    <pubDate>Thu, 21 May 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://skttl.dev/blog/smarter-redirects-when-editors-trash-content-in-umbraco/</guid>
                    <title>Smarter redirects when editors trash content in Umbraco</title>
                    <link>https://skttl.dev/blog/smarter-redirects-when-editors-trash-content-in-umbraco/</link>
                    <description><![CDATA[A new Umbraco package that replaces the default trash action. It captures the URLs of doomed content first, then suggests redirect targets using Umbraco.AI.Search, with a non-AI fallback for bulk trashes.]]></description>
                    <pubDate>Thu, 21 May 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://umbracocommunity.social/@UmbHost/116606538139138040</guid>
                    <title>UmbHost.Tables for Umbraco has had an update</title>
                    <link>https://umbracocommunity.social/@UmbHost/116606538139138040</link>
                    <description><![CDATA[UmbHost.Tables for #Umbraco has had an update courtesy of Mike Masey!This replaces the custom RTE with the fully featured tiptap RTE with all the configuration options you would expect.View source now opens in a modal windowThere is also a range of accessibility and UX improvementsMany thanks and a huge #h5yr for this PR!Grab it here:https://www.nuget.org/packages/UmbHost.Tables/17.1.0]]></description>
                    <pubDate>Wed, 20 May 2026 10:56:20 Z</pubDate>
                        <category>community</category>
                        <category>social</category>
                        <category>mastodon</category>
                </item>
                <item>
                    <guid>https://github.com/prjseal/Start-With-Markdown/</guid>
                    <title>Start With Markdown</title>
                    <link>https://github.com/prjseal/Start-With-Markdown/</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Wed, 20 May 2026 06:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                </item>
                <item>
                    <guid>https://discord.com/channels/869656431308189746/882981290662580264/1506219000525225994</guid>
                    <title> Clean starter kit for Umbraco 18 out in Beta</title>
                    <link>https://discord.com/channels/869656431308189746/882981290662580264/1506219000525225994</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Wed, 20 May 2026 06:00:00 Z</pubDate>
                        <category>community</category>
                        <category>social</category>
                        <category>discord</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/pragmaticit.umbraco.virtualmembers</guid>
                    <title>PragmaticIT.Umbraco.VirtualMembers</title>
                    <link>https://marketplace.umbraco.com/package/pragmaticit.umbraco.virtualmembers</link>
                    <description><![CDATA[Passwordless, database-free member authentication for Umbraco CMS. Protect content nodes with email-only, OTP, or MFA login &#x2014; members loaded from plain CSV files, no Umbraco Members database records required.]]></description>
                    <pubDate>Wed, 20 May 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://umbracocommunity.social/@owaincodes/116601888665115697</guid>
                    <title>UmbracoTees day May 29th</title>
                    <link>https://umbracocommunity.social/@owaincodes/116601888665115697</link>
                    <description><![CDATA[Can you believe we haven&#x27;t had an #UmbracoTees day this year yet? Well, let&#x27;s change that!! Get your Umbraco Swag on, share your photos with #umbracoTees and let&#x27;s see you all celebrate all things #umbraco May 29th 2026!https://isitumbracoteesday.today/]]></description>
                    <pubDate>Tue, 19 May 2026 15:13:52 Z</pubDate>
                        <category>community</category>
                        <category>social</category>
                        <category>mastodon</category>
                </item>
                <item>
                    <guid>https://www.youtube.com/watch?v=DcxmRjoFZwc</guid>
                    <title>Start With Markdown</title>
                    <link>https://www.youtube.com/watch?v=DcxmRjoFZwc</link>
                    <description><![CDATA[Learn about my new open source content publishing workflow called Start With Markdown&#xA;&#xA;It&#x27;s a simple workflow which triggers when you create or modify a markdown file in the posts folder of your github repo.&#xA;&#xA;When it triggers it calls some endpoints on your CMS to create the content and it returns the edit, preview and publish URLs for you.&#xA;&#xA;Here is the link to the main project that you fork and setup to call your CMS endpoints&#xA;https://github.com/prjseal/Start-With-Markdown/&#xA;&#xA;And here is the link to the demo Umbraco project and supporting libraries with the custom resolvers for unsplash and things like that to get it working with the Clean starter kit&#xA;https://github.com/prjseal/Start-With-Markdown-Umbraco-Libraries]]></description>
                    <pubDate>Tue, 19 May 2026 14:17:30 Z</pubDate>
                        <category>community</category>
                        <category>youtube</category>
                </item>
                <item>
                    <guid>https://dev.to/lauraneto/umbraco-18-and-openapi-a-heads-up-for-extension-developers-1k7</guid>
                    <title>Umbraco 18 and OpenAPI: a heads-up for extension developers</title>
                    <link>https://dev.to/lauraneto/umbraco-18-and-openapi-a-heads-up-for-extension-developers-1k7</link>
                    <description><![CDATA[&lt;p&gt;Time to upgrade your extension to Umbraco 18?&lt;br&gt;&#xA;A friendly heads up, the OpenAPI generation got an overhaul.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;code&gt;Microsoft.AspNetCore.OpenApi&lt;/code&gt; is Umbraco&#x27;s new library of choice for OpenAPI document generation, replacing &lt;code&gt;Swashbuckle.AspNetCore&lt;/code&gt;. It ships with ASP.NET Core and is maintained by Microsoft alongside the framework, which means one fewer third-party dependency to worry about.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The trade-off: if your extension wired up its own OpenAPI document on v17, it won&#x27;t compile against v18. The Swashbuckle types it relied on are gone.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Two paths forward:&lt;/p&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&#xA;&lt;strong&gt;Migrate to Microsoft OpenAPI&lt;/strong&gt;. Two options:&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;strong&gt;Use the &lt;code&gt;AddBackOfficeOpenApiDocument&lt;/code&gt; extension method&lt;/strong&gt;: Umbraco&#x27;s new helper. What the v18 template uses. Covers most extensions.&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;strong&gt;Use Microsoft&#x27;s &lt;code&gt;AddOpenApi&lt;/code&gt; method directly&lt;/strong&gt;: call &lt;code&gt;Microsoft.AspNetCore.OpenApi&lt;/code&gt; yourself. For full control.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;strong&gt;Keep using Swashbuckle&lt;/strong&gt; &lt;em&gt;(not recommended)&lt;/em&gt;. Install &lt;code&gt;Swashbuckle.AspNetCore&lt;/code&gt; in your own extension, wire it up, then plug your document into Umbraco&#x27;s Swagger UI via &lt;code&gt;AddOpenApiDocumentToUi(...)&lt;/code&gt;. When rewriting isn&#x27;t an option right now.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;&#x2139;&#xFE0F; &lt;strong&gt;Note:&lt;/strong&gt; the OpenAPI spec URL also changed from &lt;code&gt;/umbraco/swagger/{documentName}/swagger.json&lt;/code&gt; to &lt;code&gt;/umbraco/openapi/{documentName}.json&lt;/code&gt;. If you generate a client from the spec (e.g. via the v17 extension template&#x27;s &lt;code&gt;package.json&lt;/code&gt; &lt;code&gt;generate-client&lt;/code&gt; script), update the URL before regenerating.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  Use the AddBackOfficeOpenApiDocument extension method&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;We added &lt;code&gt;AddBackOfficeOpenApiDocument()&lt;/code&gt; in v18 to take the boilerplate out of registering an OpenAPI document. It&#x27;s an extension method on &lt;code&gt;IUmbracoBuilder&lt;/code&gt; that wires up Umbraco&#x27;s sensible defaults so you don&#x27;t have to.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Out of the box, the helper registers your document, scopes it to endpoints decorated with &lt;code&gt;[MapToApi(documentName)]&lt;/code&gt;, applies Umbraco&#x27;s naming conventions for schemas and operation IDs, and adds the document to the Swagger UI dropdown at &lt;code&gt;/umbraco/openapi/&lt;/code&gt;.&lt;/p&gt;&#xA;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;&#x26A0;&#xFE0F; &lt;strong&gt;Watch out:&lt;/strong&gt; the first time you call &lt;code&gt;AddBackOfficeOpenApiDocument&lt;/code&gt; (or &lt;code&gt;AddOpenApi&lt;/code&gt; directly) and build, you&#x27;ll hit &lt;code&gt;error CS9137: The &#x27;interceptors&#x27; feature is not enabled in this namespace&lt;/code&gt;. The &lt;code&gt;Microsoft.AspNetCore.OpenApi&lt;/code&gt; source generator (which surfaces your XML doc comments as descriptions in the OpenAPI document, among other compile-time enrichments) propagates through Umbraco&#x27;s project reference, but the property that enables it ships only with the Web SDK. Class-library projects don&#x27;t get it automatically, so add it to your &lt;code&gt;.csproj&lt;/code&gt;:&lt;/p&gt;&#xA;&#xA;&#xA;&lt;pre class=&quot;highlight xml&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;PropertyGroup&amp;gt;&lt;/span&gt;&#xA;  &lt;span class=&quot;nt&quot;&gt;&amp;lt;InterceptorsNamespaces&amp;gt;&lt;/span&gt;$(InterceptorsNamespaces);Microsoft.AspNetCore.OpenApi.Generated&lt;span class=&quot;nt&quot;&gt;&amp;lt;/InterceptorsNamespaces&amp;gt;&lt;/span&gt;&#xA;&lt;span class=&quot;nt&quot;&gt;&amp;lt;/PropertyGroup&amp;gt;&lt;/span&gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/blockquote&gt;&#xA;&lt;h3&gt;&#xA;  &#xA;  &#xA;  Minimal usage&#xA;&lt;/h3&gt;&#xA;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight csharp&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;UmbracoExtensionApiComposer&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IComposer&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Compose&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IUmbracoBuilder&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;        &lt;span class=&quot;n&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AddBackOfficeOpenApiDocument&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;my-api&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&lt;p&gt;This will add and configure a &quot;my-api&quot; OpenAPI document that will display the controllers/endpoints that have the attribute &lt;code&gt;[MapToApi(&quot;my-api&quot;)]&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;h3&gt;&#xA;  &#xA;  &#xA;  Typical usage&#xA;&lt;/h3&gt;&#xA;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight csharp&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;UmbracoExtensionApiComposer&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IComposer&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Compose&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IUmbracoBuilder&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;        &lt;span class=&quot;n&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AddBackOfficeOpenApiDocument&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;my-api&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;document&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;document&lt;/span&gt;&#xA;            &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;WithTitle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;My API&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&#xA;            &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;WithBackOfficeAuthentication&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&lt;p&gt;Besides adding a &quot;my-api&quot; OpenAPI document, this will set the document title to &quot;My API&quot; and declare that the document&#x27;s operations require backoffice authentication (which is what enables the &quot;Authorize&quot; flow in the Swagger UI).&lt;/p&gt;&#xA;&lt;h3&gt;&#xA;  &#xA;  &#xA;  Builder method reference&#xA;&lt;/h3&gt;&#xA;&#xA;&lt;div class=&quot;table-wrapper-paragraph&quot;&gt;&lt;table&gt;&#xA;&lt;thead&gt;&#xA;&lt;tr&gt;&#xA;&lt;th&gt;Method&lt;/th&gt;&#xA;&lt;th&gt;What it does&lt;/th&gt;&#xA;&lt;/tr&gt;&#xA;&lt;/thead&gt;&#xA;&lt;tbody&gt;&#xA;&lt;tr&gt;&#xA;&lt;td&gt;&lt;code&gt;WithTitle(string)&lt;/code&gt;&lt;/td&gt;&#xA;&lt;td&gt;Sets the document&#x27;s &lt;code&gt;Info.Title&lt;/code&gt;. Also used as the UI dropdown label unless &lt;code&gt;WithUiTitle&lt;/code&gt; is set.&lt;/td&gt;&#xA;&lt;/tr&gt;&#xA;&lt;tr&gt;&#xA;&lt;td&gt;&lt;code&gt;WithUiTitle(string)&lt;/code&gt;&lt;/td&gt;&#xA;&lt;td&gt;Overrides only the UI dropdown label, leaving &lt;code&gt;Info.Title&lt;/code&gt; untouched.&lt;/td&gt;&#xA;&lt;/tr&gt;&#xA;&lt;tr&gt;&#xA;&lt;td&gt;&lt;code&gt;ExcludeFromUi()&lt;/code&gt;&lt;/td&gt;&#xA;&lt;td&gt;Suppresses registration in the Swagger UI document dropdown. Document is still reachable at its JSON URL.&lt;/td&gt;&#xA;&lt;/tr&gt;&#xA;&lt;tr&gt;&#xA;&lt;td&gt;&lt;code&gt;WithBackOfficeAuthentication()&lt;/code&gt;&lt;/td&gt;&#xA;&lt;td&gt;Registers the backoffice OAuth2 security scheme on the document and marks operations as requiring authentication. Swagger UI uses this to prompt for login; generated clients use it to send the token.&lt;/td&gt;&#xA;&lt;/tr&gt;&#xA;&lt;tr&gt;&#xA;&lt;td&gt;&lt;code&gt;ConfigureOpenApiOptions(Action&amp;lt;OpenApiOptions&amp;gt;)&lt;/code&gt;&lt;/td&gt;&#xA;&lt;td&gt;Adds a configuration callback for the underlying &lt;code&gt;OpenApiOptions&lt;/code&gt;. Multiple calls will run in order after Umbraco&#x27;s defaults.&lt;/td&gt;&#xA;&lt;/tr&gt;&#xA;&lt;tr&gt;&#xA;&lt;td&gt;&lt;code&gt;WithJsonOptions(...)&lt;/code&gt;&lt;/td&gt;&#xA;&lt;td&gt;Sets the &lt;code&gt;JsonOptions&lt;/code&gt; used when generating the document&#x27;s schema. See Aligning schema serialization below.&lt;/td&gt;&#xA;&lt;/tr&gt;&#xA;&lt;/tbody&gt;&#xA;&lt;/table&gt;&lt;/div&gt;&#xA;&lt;h3&gt;&#xA;  &#xA;  &#xA;  Aligning schema serialization&#xA;&lt;/h3&gt;&#xA;&#xA;&lt;p&gt;Schema generation needs to use the same &lt;code&gt;JsonOptions&lt;/code&gt; your API uses at runtime, otherwise the generated SDKs and the actual payloads will not match. By default, &lt;code&gt;Microsoft.AspNetCore.OpenApi&lt;/code&gt; generates schemas using the global HTTP &lt;code&gt;JsonOptions&lt;/code&gt;, which means whoever hosts your extension can change them and that affects your schema.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;For most backoffice extensions you want the BackOffice named &lt;code&gt;JsonOptions&lt;/code&gt; (the same ones Umbraco&#x27;s Management API uses). Point the document at them with &lt;code&gt;WithJsonOptions&lt;/code&gt;:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight csharp&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;UmbracoExtensionApiComposer&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IComposer&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Compose&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IUmbracoBuilder&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;        &lt;span class=&quot;n&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AddBackOfficeOpenApiDocument&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;my-api&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;document&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;document&lt;/span&gt;&#xA;            &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;WithJsonOptions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Constants&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;JsonOptionsNames&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BackOffice&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;For this to be meaningful at runtime, your controllers also need to serialize with those same options. The v17 extension template inherits from a plain &lt;code&gt;ControllerBase&lt;/code&gt;, which uses the default options instead. Fix that by adding &lt;code&gt;[JsonOptionsName(Constants.JsonOptionsNames.BackOffice)]&lt;/code&gt; to your own base controller or to each controller directly.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Without it, the schema reflects backoffice serialization but the actual responses are serialized with the default options, and you&#x27;re back to the schema-vs-runtime mismatch.&lt;/p&gt;&#xA;&#xA;&lt;h3&gt;&#xA;  &#xA;  &#xA;  Going beyond the defaults&#xA;&lt;/h3&gt;&#xA;&#xA;&lt;p&gt;The helper is not a closed box. Anything you&#x27;d normally do on &lt;code&gt;OpenApiOptions&lt;/code&gt; (custom operation/schema/document transformers, your own &lt;code&gt;CreateSchemaReferenceId&lt;/code&gt;, a replacement operation ID transformer, etc.) is still available through &lt;code&gt;ConfigureOpenApiOptions&lt;/code&gt;. It just runs after Umbraco&#x27;s defaults, so you compose on top of them rather than starting from scratch.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;For example, registering your own schema transformer:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight csharp&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;UmbracoExtensionApiComposer&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IComposer&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Compose&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IUmbracoBuilder&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;        &lt;span class=&quot;n&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AddBackOfficeOpenApiDocument&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;my-api&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;document&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;document&lt;/span&gt;&#xA;            &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;WithTitle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;My API&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&#xA;            &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ConfigureOpenApiOptions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;options&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt;&#xA;                &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AddSchemaTransformer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MyExtensionSchemaTransformer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;()));&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;h3&gt;&#xA;  &#xA;  &#xA;  Migrating an existing composer&#xA;&lt;/h3&gt;&#xA;&#xA;&lt;p&gt;If your extension followed the shape of the v17 dotnet template, the migration is: delete the old composer body and write the &lt;code&gt;AddBackOfficeOpenApiDocument(...)&lt;/code&gt; call. Below is the same extension&#x27;s composer before and after.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;v17 (Swashbuckle)&lt;/strong&gt;&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight csharp&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;UmbracoExtensionApiComposer&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IComposer&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Compose&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IUmbracoBuilder&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;        &lt;span class=&quot;n&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Services&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AddSingleton&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IOperationIdHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CustomOperationHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;();&lt;/span&gt;&#xA;&#xA;        &lt;span class=&quot;n&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Services&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Configure&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SwaggerGenOptions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;opt&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt;&#xA;        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;            &lt;span class=&quot;n&quot;&gt;opt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SwaggerDoc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Constants&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ApiName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;OpenApiInfo&lt;/span&gt;&#xA;            &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;                &lt;span class=&quot;n&quot;&gt;Title&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;My Test Extension Backoffice API&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&#xA;            &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;&#xA;&#xA;            &lt;span class=&quot;n&quot;&gt;opt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;OperationFilter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UmbracoExtensionOperationSecurityFilter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;();&lt;/span&gt;&#xA;        &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&#xA;    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;UmbracoExtensionOperationSecurityFilter&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;BackOfficeSecurityRequirementsOperationFilterBase&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;        &lt;span class=&quot;k&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ApiName&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Constants&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ApiName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&#xA;    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CustomOperationHandler&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;OperationIdHandler&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;        &lt;span class=&quot;c1&quot;&gt;// ...&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;v18 (Microsoft OpenAPI &#x2B; new builder)&lt;/strong&gt;&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight csharp&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;UmbracoExtensionApiComposer&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IComposer&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Compose&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IUmbracoBuilder&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt;&#xA;        &lt;span class=&quot;n&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AddBackOfficeOpenApiDocument&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&#xA;            &lt;span class=&quot;n&quot;&gt;Constants&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ApiName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&#xA;            &lt;span class=&quot;n&quot;&gt;document&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;document&lt;/span&gt;&#xA;                &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;WithTitle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;My Test Extension Backoffice API&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&#xA;                &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;WithBackOfficeAuthentication&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;The helper registers &lt;code&gt;UmbracoOperationIdTransformer&lt;/code&gt; by default, so the old &lt;code&gt;IOperationIdHandler&lt;/code&gt; is no longer needed. If you want custom operation ID logic, register your own through &lt;code&gt;ConfigureOpenApiOptions&lt;/code&gt;:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight csharp&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;UmbracoExtensionApiComposer&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IComposer&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Compose&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IUmbracoBuilder&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;        &lt;span class=&quot;n&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AddBackOfficeOpenApiDocument&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;my-api&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;document&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;document&lt;/span&gt;&#xA;            &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ConfigureOpenApiOptions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;options&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt;&#xA;                &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AddOperationTransformer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;operation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt;&#xA;                &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;                    &lt;span class=&quot;n&quot;&gt;operation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;OperationId&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;$&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Description&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ActionDescriptor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RouteValues&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;action&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&#xA;                    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Task&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CompletedTask&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&#xA;                &lt;span class=&quot;p&quot;&gt;})));&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  Use Microsoft&#x27;s AddOpenApi method directly&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;If you want to register a document that isn&#x27;t a backoffice document, or you want to start from a clean slate without Umbraco&#x27;s defaults, call &lt;code&gt;AddOpenApi&lt;/code&gt; yourself. The helper is just a thin wrapper around that method. Umbraco already wires the OpenAPI routing and Swagger UI hosting, so you don&#x27;t need to call &lt;code&gt;MapOpenApi&lt;/code&gt; or configure endpoints. You only need to register your documents.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;For the transformer model itself (how operation/schema/document transformers work), see Microsoft&#x27;s &lt;a href=&quot;https://learn.microsoft.com/en-us/aspnet/core/fundamentals/openapi/customize-openapi&quot; rel=&quot;noopener noreferrer&quot;&gt;Customize OpenAPI documents&lt;/a&gt; docs.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;For Umbraco&#x27;s specifics (&lt;code&gt;[MapToApi]&lt;/code&gt; filtering via &lt;code&gt;options.ShouldInclude&lt;/code&gt;, schema/operation ID conventions, the public &lt;code&gt;UmbracoSchemaIdGenerator.Generate(type)&lt;/code&gt; helper), see the &lt;a href=&quot;https://docs.umbraco.com/umbraco-cms/18.latest/extend-your-project/server-side-extensions/api-versioning-and-openapi&quot; rel=&quot;noopener noreferrer&quot;&gt;API versioning and OpenAPI&lt;/a&gt; docs.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;A few things worth remembering:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;strong&gt;Backoffice authentication&lt;/strong&gt;: call &lt;code&gt;options.AddBackofficeSecurityRequirements()&lt;/code&gt; (from &lt;code&gt;Umbraco.Cms.Api.Management.OpenApi&lt;/code&gt;) instead of subclassing &lt;code&gt;BackOfficeSecurityRequirementsOperationFilterBase&lt;/code&gt;.&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;strong&gt;Swagger UI registration&lt;/strong&gt;: documents are no longer auto-listed. Call &lt;code&gt;services.AddOpenApiDocumentToUi(documentName, uiTitle)&lt;/code&gt; to surface yours in the dropdown.&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;strong&gt;&lt;code&gt;InterceptorsNamespaces&lt;/code&gt; opt-in&lt;/strong&gt;: same as the helper path. See the Watch out callout at the top of the helper section.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  Keep using Swashbuckle&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;Not recommended.&lt;/strong&gt; Consider this only if rewriting a complex Swashbuckle setup isn&#x27;t feasible right now. Trade-offs:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Extra dependency on &lt;code&gt;Swashbuckle.AspNetCore&lt;/code&gt;.&lt;/li&gt;&#xA;&lt;li&gt;OpenAPI 3.0 output, whereas the rest of Umbraco&#x27;s documents emit 3.1.&lt;/li&gt;&#xA;&lt;li&gt;Extra wiring you maintain yourself.&lt;/li&gt;&#xA;&lt;li&gt;Both libraries depend on &lt;code&gt;Microsoft.OpenApi&lt;/code&gt;. A breaking change there that Swashbuckle doesn&#x27;t follow leaves your extension incompatible with the rest of the stack.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;If you still want to go this route, see the &lt;a href=&quot;https://github.com/domaindrivendev/Swashbuckle.AspNetCore#getting-started&quot; rel=&quot;noopener noreferrer&quot;&gt;Swashbuckle.AspNetCore README&lt;/a&gt; for general setup. The rest of this section is the Umbraco-specific wiring.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;1. Install the NuGet package&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Add a &lt;code&gt;PackageReference&lt;/code&gt; to &lt;code&gt;Swashbuckle.AspNetCore&lt;/code&gt; in your extension&#x27;s &lt;code&gt;.csproj&lt;/code&gt; (or &lt;code&gt;dotnet add package Swashbuckle.AspNetCore&lt;/code&gt;).&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;2. Register Swashbuckle and your document in a composer&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;In v17, Umbraco called &lt;code&gt;AddSwaggerGen&lt;/code&gt; for you and your extension only configured &lt;code&gt;SwaggerGenOptions&lt;/code&gt;. In v18 you have to call it yourself:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight csharp&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;UmbracoExtensionApiComposer&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IComposer&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Compose&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IUmbracoBuilder&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;        &lt;span class=&quot;n&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Services&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AddSwaggerGen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;opt&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt;&#xA;        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;            &lt;span class=&quot;n&quot;&gt;opt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SwaggerDoc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Constants&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ApiName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;OpenApiInfo&lt;/span&gt;&#xA;            &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;                &lt;span class=&quot;n&quot;&gt;Title&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;My Test Extension Backoffice API&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&#xA;                &lt;span class=&quot;n&quot;&gt;Version&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;1.0&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&#xA;            &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;&#xA;&#xA;            &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;previousDocInclusion&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;opt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SwaggerGeneratorOptions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DocInclusionPredicate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&#xA;            &lt;span class=&quot;n&quot;&gt;opt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;DocInclusionPredicate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;docName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;apiDesc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt;&#xA;                &lt;span class=&quot;n&quot;&gt;docName&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Constants&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ApiName&lt;/span&gt;&#xA;                    &lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;apiDesc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ActionDescriptor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;HasMapToApiAttribute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;docName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&#xA;                    &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;previousDocInclusion&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Invoke&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;docName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;apiDesc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;??&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&#xA;&#xA;            &lt;span class=&quot;c1&quot;&gt;// any operation filters, schema filters, or other v17 setup you had...&lt;/span&gt;&#xA;        &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;3. Host the Swagger JSON middleware via an &lt;code&gt;IUmbracoPipelineFilter&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Umbraco no longer calls &lt;code&gt;app.UseSwagger()&lt;/code&gt;, so the middleware that serves the Swagger JSON isn&#x27;t running. Add it through Umbraco&#x27;s pipeline filter, and set the &lt;code&gt;RouteTemplate&lt;/code&gt; to match &lt;code&gt;UmbracoOpenApiOptions.RouteTemplate&lt;/code&gt; (default &lt;code&gt;umbraco/openapi/{documentName}.json&lt;/code&gt;) so the dropdown link resolves.&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight csharp&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;UmbracoExtensionApiComposer&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IComposer&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Compose&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IUmbracoBuilder&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;        &lt;span class=&quot;n&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Services&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Configure&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UmbracoPipelineOptions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;options&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt;&#xA;        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;            &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AddFilter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;UmbracoPipelineFilter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Swashbuckle&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&#xA;            &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;                &lt;span class=&quot;n&quot;&gt;PostPipeline&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;app&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt;&#xA;                &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;                    &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;openApiOptions&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ApplicationServices&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetRequiredService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IOptions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UmbracoOpenApiOptions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&amp;gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&#xA;                    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;openApiOptions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Enabled&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&#xA;                    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;                        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&#xA;                    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&#xA;                    &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;routeTemplate&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;openApiOptions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RouteTemplate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&#xA;                    &lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;UseWhen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&#xA;                        &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Path&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;routeTemplate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Replace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{documentName}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Constants&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ApiName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;EnsureStartsWith&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sc&quot;&gt;&#x27;/&#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;&#xA;                        &lt;span class=&quot;n&quot;&gt;branch&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;branch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;UseSwagger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RouteTemplate&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;routeTemplate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;&#xA;                &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&#xA;            &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;&#xA;        &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;Scope the middleware to your own document&#x27;s URL. Otherwise Swashbuckle intercepts requests for Umbraco&#x27;s own documents (Management, Delivery) and returns 404 because they aren&#x27;t registered with &lt;code&gt;AddSwaggerGen&lt;/code&gt;.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;4. Register the document in the Swagger UI dropdown&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Register the document in Umbraco&#x27;s Swagger UI dropdown:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight csharp&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;UmbracoExtensionApiComposer&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IComposer&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Compose&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IUmbracoBuilder&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;        &lt;span class=&quot;n&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Services&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AddOpenApiDocumentToUi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Constants&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ApiName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;My API&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  TL;DR&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;The helper is the simplest option for most extensions. &lt;code&gt;AddBackOfficeOpenApiDocument()&lt;/code&gt; is what the v18 template uses, gives you Umbraco&#x27;s sensible defaults out of the box (naming conventions, Swagger UI registration, JsonOptions alignment), and lets you register an OpenAPI document in a single call.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Calling &lt;code&gt;AddOpenApi&lt;/code&gt; yourself is the standard ASP.NET Core approach and works fine. It means more wiring and code to maintain, so reach for it when you need full control (non-backoffice documents, or skipping the Umbraco defaults).&lt;/p&gt;&#xA;&#xA;&lt;p&gt;If rewriting really isn&#x27;t an option right now, keeping Swashbuckle as your own dependency and plugging into the dropdown via &lt;code&gt;AddOpenApiDocumentToUi(...)&lt;/code&gt; will get you through, but plan to revisit when you can.&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  Further reading&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;a href=&quot;https://github.com/umbraco/Announcements/issues/32&quot; rel=&quot;noopener noreferrer&quot;&gt;Announcements #32&lt;/a&gt;: the official announcement, with the full set of changes and reasoning&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;a href=&quot;https://docs.umbraco.com/umbraco-cms/18.latest/extend-your-project/server-side-extensions/custom-backoffice-api&quot; rel=&quot;noopener noreferrer&quot;&gt;Custom Backoffice API&lt;/a&gt;: end-to-end backoffice API setup&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;a href=&quot;https://docs.umbraco.com/umbraco-cms/18.latest/extend-your-project/server-side-extensions/api-versioning-and-openapi&quot; rel=&quot;noopener noreferrer&quot;&gt;API versioning and OpenAPI&lt;/a&gt;: schema IDs, operation IDs, route configuration, endpoint filtering&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;a href=&quot;https://docs.umbraco.com/umbraco-cms/18.latest/get-started/upgrading-and-migrating/version-specific#umbraco-18&quot; rel=&quot;noopener noreferrer&quot;&gt;Umbraco 18 version-specific upgrade docs&lt;/a&gt;: official migration reference&lt;/li&gt;&#xA;&lt;/ul&gt;]]></description>
                    <pubDate>Tue, 19 May 2026 13:37:37 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://www.justnik.me/blog/why-i-built-a-passwordless-library-for-umbraco</guid>
                    <title>Building a Passwordless Authentication Library for Umbraco - Part 1: Why?</title>
                    <link>https://www.justnik.me/blog/why-i-built-a-passwordless-library-for-umbraco</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Tue, 19 May 2026 12:36:58 Z</pubDate>
                        <category>blog</category>
                        <category>community</category>
                </item>
                <item>
                    <guid>https://github.com/limbo-works/Limbo.Umbraco.FilterList/releases/tag/v13.0.0-alpha004</guid>
                    <title>Limbo.Umbraco.FilterList 13.0.0-alpha004</title>
                    <link>https://github.com/limbo-works/Limbo.Umbraco.FilterList/releases/tag/v13.0.0-alpha004</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Tue, 19 May 2026 10:55:08 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                </item>
                <item>
                    <guid>https://github.com/limbo-works/Limbo.Umbraco.FilterList/releases/tag/v13.0.0-alpha003</guid>
                    <title>Limbo.Umbraco.FilterList 13.0.0-alpha003</title>
                    <link>https://github.com/limbo-works/Limbo.Umbraco.FilterList/releases/tag/v13.0.0-alpha003</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Tue, 19 May 2026 10:33:05 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                </item>
                <item>
                    <guid>https://umbraco.com/blog/ai-on-your-terms-how-umbraco-reimagines-ai/</guid>
                    <title>AI on Your Terms: How Umbraco Reimagines AI</title>
                    <link>https://umbraco.com/blog/ai-on-your-terms-how-umbraco-reimagines-ai/</link>
                    <description><![CDATA[AI is often introduced as a shortcut: more content, more insights, more efficiency. But for many organizations, especially those responsible for digital platforms, the initial excitement is quickly followed by unease. Who is in control of the output? What happens to sensitive data? And how do you ensure that automation doesn&#x2019;t quietly erode quality, tone, or accountability?]]></description>
                    <pubDate>Tue, 19 May 2026 00:00:00 Z</pubDate>
                        <category>hq</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://umbraco.com/blog/uprofile-may-2026-bernadet-goey/</guid>
                    <title>uProfile May 2026 - Bernadet Goey</title>
                    <link>https://umbraco.com/blog/uprofile-may-2026-bernadet-goey/</link>
                    <description><![CDATA[Meet Bernadet: Former PHP-specialist, now a confident Umbraco Developer, looking to give back to the community that supported her journey]]></description>
                    <pubDate>Mon, 18 May 2026 00:00:00 Z</pubDate>
                        <category>hq</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/hcs.passwordless.magiclink</guid>
                    <title>HCS.Passwordless.MagicLink</title>
                    <link>https://marketplace.umbraco.com/package/hcs.passwordless.magiclink</link>
                    <description><![CDATA[Magic link passwordless authentication for Umbraco 17 members. Send a one-click sign-in link by email &#x2014; no passwords required. Includes built-in rate limiting, single-use tokens, and customisable branded emails.]]></description>
                    <pubDate>Mon, 18 May 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/hcs.passwordless.webauthn</guid>
                    <title>HCS.Passwordless.WebAuthn</title>
                    <link>https://marketplace.umbraco.com/package/hcs.passwordless.webauthn</link>
                    <description><![CDATA[WebAuthn/FIDO2 passkey add-on for Umbraco 17 passwordless member authentication. Enable hardware-backed biometric or security-key sign-in via the browser&#x27;s Credential Management API. No passwords required.]]></description>
                    <pubDate>Mon, 18 May 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/hcs.passwordless.otp</guid>
                    <title>HCS.Passwordless.Otp</title>
                    <link>https://marketplace.umbraco.com/package/hcs.passwordless.otp</link>
                    <description><![CDATA[One-time password (OTP) email add-on for Umbraco 17 passwordless member authentication. Delivers a short numeric code by email that the member enters to sign in. No passwords required.]]></description>
                    <pubDate>Mon, 18 May 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://skttl.dev/blog/releasing-image-hotspot-17/</guid>
                    <title>Releasing Image Hotspot 17.0.0</title>
                    <link>https://skttl.dev/blog/releasing-image-hotspot-17/</link>
                    <description><![CDATA[What&#x27;s new in version 17.0.0 of the Image Hotspot property editor: Umbraco 17 support, block editor fixes, localization in 29 languages, and a new versioning scheme.]]></description>
                    <pubDate>Mon, 18 May 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://jcdc.dev/blog/share-the-love-bringing-h5yr-to-jcdcdev</guid>
                    <title>Share the Love - Bringing #H5YR to jcdc.dev</title>
                    <link>https://jcdc.dev/blog/share-the-love-bringing-h5yr-to-jcdcdev</link>
                    <description><![CDATA[I&#x27;ve added the new #H5YR widget to my sites. Send a virtual High Five!]]></description>
                    <pubDate>Sat, 16 May 2026 09:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://uskinned.net/blog/uskinned-site-builder-for-umbraco-17/</guid>
                    <title>uSkinned Site Builder for Umbraco 17</title>
                    <link>https://uskinned.net/blog/uskinned-site-builder-for-umbraco-17/</link>
                    <description><![CDATA[&#x1F4E3; Introducing &#x1F941;&#xA;&#xA;uSkinned Site Builder for Umbraco 17 &#x1F929;&#xA;&#xA;Full support for Umbraco 17 is now available for uSkinned Site Builder. Install or upgrade today.]]></description>
                    <pubDate>Fri, 15 May 2026 14:03:31 Z</pubDate>
                        <category>blog</category>
                        <category>community</category>
                </item>
                <item>
                    <guid>https://www.linkedin.com/pulse/from-zero-working-product-two-hours-adam-shallcross-7zeme/</guid>
                    <title>From zero to working product in two hours</title>
                    <link>https://www.linkedin.com/pulse/from-zero-working-product-two-hours-adam-shallcross-7zeme/</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Fri, 15 May 2026 07:58:10 Z</pubDate>
                        <category>social</category>
                        <category>linkedin</category>
                        <category>community</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.ai.agent.ui</guid>
                    <title>Umbraco.AI.Agent.UI</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.ai.agent.ui</link>
                    <description><![CDATA[Shared chat UI components for Umbraco AI Agent surfaces]]></description>
                    <pubDate>Fri, 15 May 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.ai.agent.copilot</guid>
                    <title>Umbraco.AI.Agent.Copilot</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.ai.agent.copilot</link>
                    <description><![CDATA[Copilot chat UI for Umbraco AI Agent]]></description>
                    <pubDate>Fri, 15 May 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/modgift.umbraco.breakable</guid>
                    <title>Modgift.Umbraco.Breakable</title>
                    <link>https://marketplace.umbraco.com/package/modgift.umbraco.breakable</link>
                    <description><![CDATA[A Breakable property editor for Umbraco CMS that lets editors mark soft-hyphen break points inside text values using | as a delimiter.]]></description>
                    <pubDate>Fri, 15 May 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/our.umbraco.propertytooltip</guid>
                    <title>Our.Umbraco.PropertyToolTip</title>
                    <link>https://marketplace.umbraco.com/package/our.umbraco.propertytooltip</link>
                    <description><![CDATA[Property ToolTip keeps Umbraco property descriptions available, but shows them as small tooltip help text beside each property label.]]></description>
                    <pubDate>Fri, 15 May 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://medium.com/@ben_46907/swiftui-is-a-disaster-9706ffe6016c?source=rss------umbraco-5</guid>
                    <title>SwiftUI is a Disaster</title>
                    <link>https://medium.com/@ben_46907/swiftui-is-a-disaster-9706ffe6016c?source=rss------umbraco-5</link>
                    <description><![CDATA[&lt;div class=&quot;medium-feed-item&quot;&gt;&lt;p class=&quot;medium-feed-image&quot;&gt;&lt;a href=&quot;https://medium.com/@ben_46907/swiftui-is-a-disaster-9706ffe6016c?source=rss------umbraco-5&quot;&gt;&lt;img src=&quot;https://cdn-images-1.medium.com/max/800/0*yYaREfb1AnLyqkU5.png&quot; width=&quot;800&quot;&gt;&lt;/a&gt;&lt;/p&gt;&lt;p class=&quot;medium-feed-snippet&quot;&gt;I&amp;#x2019;ll admit it. I&amp;#x2019;m still programming for Apple platforms using Objective-C, AppKit and UIKit.&lt;/p&gt;&lt;p class=&quot;medium-feed-link&quot;&gt;&lt;a href=&quot;https://medium.com/@ben_46907/swiftui-is-a-disaster-9706ffe6016c?source=rss------umbraco-5&quot;&gt;Continue reading on Medium &#xBB;&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;]]></description>
                    <pubDate>Thu, 14 May 2026 17:24:48 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://joe.gl/ombek/blog/umbicosaurus-deextinction/</guid>
                    <title>The Umbicosaurus De-Extinction: The Community Effort that Brought a Better Icon Picker to Umbraco 17.4</title>
                    <link>https://joe.gl/ombek/blog/umbicosaurus-deextinction/</link>
                    <description><![CDATA[In 2021, I dreamed of improving the icon picker in the Umbraco backoffice and today, in Umbraco 17.4, the package I started is making a splash as part of Core!&#xA;&#xA;This is the story of Umbicosaurus.]]></description>
                    <pubDate>Thu, 14 May 2026 09:58:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://www.nuget.org/packages/Articulate/6.0.0-rc.2</guid>
                    <title>Articulate v6 RC 2</title>
                    <link>https://www.nuget.org/packages/Articulate/6.0.0-rc.2</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Thu, 14 May 2026 08:29:22 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                </item>
                <item>
                    <guid>https://uskinned.net/blog/umbraco-scotland-meetup-glasgow-edition/</guid>
                    <title>Umbraco Scotland: Glasgow Edition, May 2026</title>
                    <link>https://uskinned.net/blog/umbraco-scotland-meetup-glasgow-edition/</link>
                    <description><![CDATA[Umbraco Scotland: Glasgow Edition, May 2026&#xA;&#xA;A great evening, bringing the Umbraco Scotland community together to share ideas and insights.]]></description>
                    <pubDate>Wed, 13 May 2026 09:00:58 Z</pubDate>
                        <category>blog</category>
                        <category>community</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.smartredirectsuggester</guid>
                    <title>Umbraco.Community.SmartRedirectSuggester</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.smartredirectsuggester</link>
                    <description><![CDATA[Improve the Umbraco trash flow by suggesting redirect targets for published content before it is moved to the recycle bin.]]></description>
                    <pubDate>Wed, 13 May 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.holdyourhorses</guid>
                    <title>Umbraco.Community.HoldYourHorses</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.holdyourhorses</link>
                    <description><![CDATA[Replaces the Save and Publish button in the Umbraco backoffice with a configurable, cancellable countdown &#x2014; gives editors a short window to catch mistakes before content goes live.]]></description>
                    <pubDate>Wed, 13 May 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/doctypedoctor</guid>
                    <title>DocTypeDoctor</title>
                    <link>https://marketplace.umbraco.com/package/doctypedoctor</link>
                    <description><![CDATA[...]]></description>
                    <pubDate>Wed, 13 May 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://docs.umbraco.com/umbraco-cloud/release-notes/overview-2026/2026-05-releasenotes</guid>
                    <title>May 2026 Cloud Release Notes</title>
                    <link>https://docs.umbraco.com/umbraco-cloud/release-notes/overview-2026/2026-05-releasenotes</link>
                    <description><![CDATA[May 2026 | Cloud | Umbraco Documentation]]></description>
                    <pubDate>Tue, 12 May 2026 15:21:19 Z</pubDate>
                        <category>hq</category>
                </item>
                <item>
                    <guid>https://www.etive-mor.com/blog/carlini-style-vulnerability-hunting-on-a-budget/</guid>
                    <title>Carlini-style software vulnerability hunting, on a budget</title>
                    <link>https://www.etive-mor.com/blog/carlini-style-vulnerability-hunting-on-a-budget/</link>
                    <description><![CDATA[https://www.etive-mor.com/blog/carlini-style-vulnerability-hunting-on-a-budget/Nicholas Carlini did a great talk at [un]prompted a few weeks ago, where he detailed how Anthropic were using LLMs to automate software vulnerability discovery. In this post, I take a look at replicating his process in the Umbraco-CMS repository, for less than 1% the cost.#umbraco #security #llm #ai]]></description>
                    <pubDate>Tue, 12 May 2026 13:31:23 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://umbracocommunity.social/@owaincodes/116561041760397682</guid>
                    <title>The new H5YR.com widget is now LIVE!</title>
                    <link>https://umbracocommunity.social/@owaincodes/116561041760397682</link>
                    <description><![CDATA[The new H5YR.com widget is now LIVE! https://h5yr.com/h5yr-widget/ #umbraco]]></description>
                    <pubDate>Tue, 12 May 2026 13:01:00 Z</pubDate>
                        <category>community</category>
                        <category>social</category>
                        <category>mastodon</category>
                </item>
                <item>
                    <guid>https://umbracocommunity.social/@owaincodes/116560322535140460</guid>
                    <title>H5YR.com is now on Umbraco 17</title>
                    <link>https://umbracocommunity.social/@owaincodes/116560322535140460</link>
                    <description><![CDATA[H5YR.com is now on #Umbraco 17 &#x1F389; Thanks @UmbHost for the help with the deployment yesterday. #h5yr]]></description>
                    <pubDate>Tue, 12 May 2026 07:08:15 Z</pubDate>
                        <category>community</category>
                        <category>social</category>
                        <category>mastodon</category>
                </item>
                <item>
                    <guid>https://www.linkedin.com/posts/owainwilliams_h5yr-community-umbraco-share-7459538862323924992-iV5D/</guid>
                    <title>H5YR embeddable widget progress</title>
                    <link>https://www.linkedin.com/posts/owainwilliams_h5yr-community-umbraco-share-7459538862323924992-iV5D/</link>
                    <description><![CDATA[H5YR update: https://www.linkedin.com/posts/owainwilliams_h5yr-community-umbraco-share-7459538862323924992-iV5D?utm_source=share&amp;utm_medium=member_ios&amp;rcm=ACoAAABj9KwBjr581HKBv-M3TbQu69Ia79rmfPw&#xA;&#xA;Sent from my iPhone]]></description>
                    <pubDate>Mon, 11 May 2026 16:52:10 Z</pubDate>
                        <category>linkedin</category>
                        <category>community</category>
                        <category>social</category>
                </item>
                <item>
                    <guid>https://codeshare.co.uk/blog/designing-an-ai-agent-skill-for-adding-a-page-type-to-umbraco/</guid>
                    <title>Designing an AI Agent skill for adding a page type to Umbraco</title>
                    <link>https://codeshare.co.uk/blog/designing-an-ai-agent-skill-for-adding-a-page-type-to-umbraco/</link>
                    <description><![CDATA[Explore how experienced developers are building AI skills to scaffold Umbraco features. See the conventions and decisions that make page type creation effortless.]]></description>
                    <pubDate>Mon, 11 May 2026 11:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://www.linkedin.com/posts/adamshallcross_quick-update-on-the-ai-search-package-im-ugcPost-7457449420633042944-t2zb</guid>
                    <title>Adam Shallcross AI based search package progress</title>
                    <link>https://www.linkedin.com/posts/adamshallcross_quick-update-on-the-ai-search-package-im-ugcPost-7457449420633042944-t2zb</link>
                    <description><![CDATA[Untitled: https://www.linkedin.com/posts/adamshallcross_quick-update-on-the-ai-search-package-im-ugcPost-7457449420633042944-t2zb?utm_source=share&amp;utm_medium=member_ios&amp;rcm=ACoAAABj9KwBjr581HKBv-M3TbQu69Ia79rmfPw&#xA;&#xA;Sent from my iPhone]]></description>
                    <pubDate>Mon, 11 May 2026 06:41:24 Z</pubDate>
                        <category>community</category>
                        <category>social</category>
                        <category>linkedin</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/diplo.translator</guid>
                    <title>Diplo Translator</title>
                    <link>https://marketplace.umbraco.com/package/diplo.translator</link>
                    <description><![CDATA[Diplo Translator | Umbraco Marketplace]]></description>
                    <pubDate>Fri, 08 May 2026 08:28:41 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.ai.chatbot</guid>
                    <title>Umbraco.Community.AI.Chatbot</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.ai.chatbot</link>
                    <description><![CDATA[Drops a public-facing, AI-powered chat widget on a website&#x27;s frontend. End users on the public site type a question; the package runs a semantic search over the site&#x27;s Umbraco content (Umbraco.AI.Search), feeds the matched pages into an Umbraco.AI.Agent, and streams a grounded answer back with cited source pages and follow-up suggestions.&#xA;&#xA;The official Umbraco.AI.* packages expose chat only inside the backoffice. There is no path for an anonymous site visitor to ask questions of the site&#x27;s content. This community package fills that gap.&#xA;&#xA;Key features:&#xA;- Public-facing widget (drop in one &lt;script&gt; tag)&#xA;- Grounded answers with cited source pages&#xA;- Suggested follow-up questions&#xA;- Streaming responses (SSE)&#xA;- Per-IP rate limiting and request size caps&#xA;- Per-instance configuration in the backoffice (welcome message, agent, fallback)&#xA;&#xA;Requires Umbraco CMS 17.3&#x2B;, Umbraco.AI 1.10&#x2B;, Umbraco.AI.Agent 1.9&#x2B;, and a populated Umbraco.AI.Search index.]]></description>
                    <pubDate>Fri, 08 May 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://dev.to/cultiv/bootstrapping-umbraco-modelsbuilder-on-an-empty-site-age</guid>
                    <title>Bootstrapping Umbraco ModelsBuilder on an empty site</title>
                    <link>https://dev.to/cultiv/bootstrapping-umbraco-modelsbuilder-on-an-empty-site-age</link>
                    <description><![CDATA[The rest of this post was written with Claude AI. Here&#x27;s the simple problem I seem to get myself into often: &#xA;&#xA;I have views that need a strongly typed model, but modelsbuilder hasn&#x27;t put the models on disk so Umbraco completely fails to start. dotnet run just fails &#x1F631; But I need to get into the backoffice to generate the models; difficult when Umbraco doesn&#x27;t even run.&#xA;&#xA;After I encountered this today, I finally took some time to figure out what the easiest way is to get this fixed. What follows is the summary of what Claude did for me:&#xA;&#xA;&#xA;&#xA;&#xA;Dropped a set of strongly-typed views (home.cshtml, Author.cshtml, etc.) into a fresh Umbraco site and ran straight into the chicken-and-egg problem every Umbraco developer eventually meets:&#xA;&#xA;&#xA;The views reference Umbraco.Cms.Web.Common.PublishedModels.Home (and friends).&#xA;Those classes are generated by ModelsBuilder from document types that live in the database.&#xA;The database is empty until the site has run at least once.&#xA;The site won&#x27;t build because the views don&#x27;t compile, so it can&#x27;t run.&#xA;&#xA;&#xA;Here&#x27;s the little dance to break the cycle.&#xA;&#xA;&#xA;  &#xA;  &#xA;  1. Turn off Razor compile-on-build&#xA;&#xA;&#xA;In the .csproj:&#xA;&#xA;&#xA;&#xA;&lt;RazorCompileOnBuild&gt;false&lt;/RazorCompileOnBuild&gt;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;The build now skips the views entirely instead of failing on the missing PublishedModels.* types.&#xA;&#xA;&#xA;  &#xA;  &#xA;  2. Switch ModelsBuilder to manual mode&#xA;&#xA;&#xA;In appsettings.json:&#xA;&#xA;&#xA;&#xA;&quot;ModelsBuilder&quot;: {&#xA;  &quot;ModelsMode&quot;: &quot;SourceCodeManual&quot;&#xA;}&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;SourceCodeManual is the only mode that gives you a Generate models button in the backoffice. The other three:&#xA;&#xA;&#xA;&#xA;&#xA;Mode&#xA;Files?&#xA;Trigger&#xA;&#xA;&#xA;&#xA;&#xA;Nothing&#xA;none&#xA;&#x2014;&#xA;&#xA;&#xA;InMemoryAuto&#xA;in-memory only&#xA;auto&#xA;&#xA;&#xA;SourceCodeManual&#xA;~/umbraco/models/*.cs&#xA;button&#xA;&#xA;&#xA;SourceCodeAuto&#xA;~/umbraco/models/*.cs&#xA;auto on schema change&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;  &#xA;  &#xA;  3. Start the site&#xA;&#xA;&#xA;dotnet run. The build succeeds (views aren&#x27;t compiled), the app starts, and the backoffice comes up. Frontend pages will 404 or 500 right now &#x2014; that&#x27;s expected and we don&#x27;t care yet.&#xA;&#xA;&#xA;  &#xA;  &#xA;  4. Click the button&#xA;&#xA;&#xA;Backoffice &#x2192; Settings &#x2192; Models Builder &#x2192; Generate models.&#xA;&#xA;.cs files appear in umbraco/models/ &#x2014; one per document type. These are the classes the views were waiting on.&#xA;&#xA;&#xA;  &#xA;  &#xA;  5. Stop the site&#xA;&#xA;&#xA;Ctrl&#x2B;C.&#xA;&#xA;&#xA;  &#xA;  &#xA;  6. Re-enable Razor compile-on-build&#xA;&#xA;&#xA;Remove the line we added in step 1:&#xA;&#xA;&#xA;&#xA;&lt;!-- &lt;RazorCompileOnBuild&gt;false&lt;/RazorCompileOnBuild&gt;  &#x2190; delete this --&gt;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;  &#xA;  &#xA;  7. Start the site again&#xA;&#xA;&#xA;dotnet run. Build picks up the generated models, compiles the views against them, the home page renders.&#xA;&#xA;&#xA;  &#xA;  &#xA;  Why the dance is needed&#xA;&#xA;&#xA;RazorCompileOnBuild=false alone isn&#x27;t a real fix &#x2014; it just moves the compile error from build time to the moment a frontend page is hit. Without runtime compilation registered, Umbraco&#x27;s view-engine lookup returns &quot;no physical template file found&quot; and serves a 404. You&#x27;ll see this in the logs:&#xA;&#xA;&#xA;&#xA;&quot;No physical template file was found for template home&quot;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;&#xA;The actual fix is to get the models on disk. The flag just buys you the brief window between &quot;build doesn&#x27;t run&quot; and &quot;models exist&quot; so you can boot the backoffice and press the button.&#xA;&#xA;Once the models are committed to source control, none of this matters &#x2014; the next clone builds clean from the start.]]></description>
                    <pubDate>Thu, 07 May 2026 15:24:58 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://examinex.online/2026/04/16/ai-semantic-ranking-for-azure-search</guid>
                    <title>AI Semantic Ranking with ExamineX and Azure Search</title>
                    <link>https://examinex.online/2026/04/16/ai-semantic-ranking-for-azure-search</link>
                    <description><![CDATA[AI Semantic Ranking with ExamineX and Azure Search]]></description>
                    <pubDate>Thu, 07 May 2026 14:36:09 Z</pubDate>
                        <category>blog</category>
                        <category>community</category>
                </item>
                <item>
                    <guid>https://samsolutions.medium.com/umbraco-vs-wordpress-which-cms-platform-is-best-for-your-business-43863d7710c9?source=rss------umbraco-5</guid>
                    <title>Umbraco vs WordPress: Which CMS Platform Is Best for Your Business?</title>
                    <link>https://samsolutions.medium.com/umbraco-vs-wordpress-which-cms-platform-is-best-for-your-business-43863d7710c9?source=rss------umbraco-5</link>
                    <description><![CDATA[&lt;div class=&quot;medium-feed-item&quot;&gt;&lt;p class=&quot;medium-feed-image&quot;&gt;&lt;a href=&quot;https://samsolutions.medium.com/umbraco-vs-wordpress-which-cms-platform-is-best-for-your-business-43863d7710c9?source=rss------umbraco-5&quot;&gt;&lt;img src=&quot;https://cdn-images-1.medium.com/max/1536/1*dxgdjM-1uAleskWDzfMX1Q.png&quot; width=&quot;1536&quot;&gt;&lt;/a&gt;&lt;/p&gt;&lt;p class=&quot;medium-feed-snippet&quot;&gt;Choosing the right Content Management System (CMS) is a foundational decision for any digital strategy. The market offers a wide spectrum&amp;#x2026;&lt;/p&gt;&lt;p class=&quot;medium-feed-link&quot;&gt;&lt;a href=&quot;https://samsolutions.medium.com/umbraco-vs-wordpress-which-cms-platform-is-best-for-your-business-43863d7710c9?source=rss------umbraco-5&quot;&gt;Continue reading on Medium &#xBB;&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;]]></description>
                    <pubDate>Thu, 07 May 2026 14:31:51 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://github.com/umbraco/Announcements/issues/35</guid>
                    <title>[Breaking change]: Remove the built-in Bootstrap 3 horizontal forms theme from Umbraco Forms</title>
                    <link>https://github.com/umbraco/Announcements/issues/35</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Thu, 07 May 2026 14:02:35 Z</pubDate>
                        <category>hq</category>
                        <category>announcement</category>
                </item>
                <item>
                    <guid>https://github.com/umbraco/Announcements/issues/34</guid>
                    <title>[Breaking change]: Replace Pikaday with native HTML date input in the Umbraco Forms default theme</title>
                    <link>https://github.com/umbraco/Announcements/issues/34</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Thu, 07 May 2026 14:00:29 Z</pubDate>
                        <category>hq</category>
                        <category>announcement</category>
                </item>
                <item>
                    <guid>https://github.com/umbraco/Announcements/issues/33</guid>
                    <title>[Breaking change]: Remove jQuery Validation support from Umbraco Forms client-side scripts</title>
                    <link>https://github.com/umbraco/Announcements/issues/33</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Thu, 07 May 2026 13:58:03 Z</pubDate>
                        <category>hq</category>
                        <category>announcement</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.aivisibility</guid>
                    <title>Umbraco.Community.AiVisibility</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.aivisibility</link>
                    <description><![CDATA[Make your Umbraco site visible to AI search engines (ChatGPT, Claude, Perplexity, Gemini, Bing Copilot) and give editors visibility into who&#x27;s reading the site. Drop-in for Umbraco v17&#x2B; with zero configuration on a typical site.&#xA;&#xA;At install time, every published page becomes reachable as Markdown via /{path}.md or via the standard Accept: text/markdown content negotiation header. Two more public routes ship: /llms.txt (an RFC-style index of every published page) and /llms-full.txt (the concatenated full-Markdown export, hard-capped at a configurable byte limit). All three surfaces are publish-driven cache invalidated and hot-path-protected (If-None-Match &#x2192; 304 &#x2192; single-flight on cache miss).&#xA;&#xA;Two Backoffice dashboards appear under Settings: AI Visibility (site name, summary, per-doctype exclusion, per-page opt-out) and AI Traffic (read-only dashboard showing every AI / human / crawler hit by classification, with date filtering). A Health Check warns when /robots.txt blocks AI crawlers you might not want to block.&#xA;&#xA;Architectural principle: the Umbraco template is the canonical visual form of content. The package renders pages through Umbraco&#x27;s normal Razor pipeline and converts the resulting HTML to Markdown &#x2014; it does NOT walk content properties or template-fork. Whatever your Razor templates produce (Block List, Block Grid, view components, third-party renderers) is what the AI gets, in clean Markdown form.&#xA;&#xA;Six DI extension points let you override extraction, request logging, robots auditing, settings resolution, and UA classification without forking. Apache 2.0 licensed.]]></description>
                    <pubDate>Thu, 07 May 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/webwonders.umbraco.blockpicker</guid>
                    <title>Webwonders.Umbraco.BlockPicker</title>
                    <link>https://marketplace.umbraco.com/package/webwonders.umbraco.blockpicker</link>
                    <description><![CDATA[A block picker property editor for Umbraco.]]></description>
                    <pubDate>Thu, 07 May 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.ai.mistral</guid>
                    <title>Umbraco.AI.Mistral</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.ai.mistral</link>
                    <description><![CDATA[Mistral provider for Umbraco AI]]></description>
                    <pubDate>Thu, 07 May 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.ai.togetherai</guid>
                    <title>Umbraco.AI.TogetherAI</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.ai.togetherai</link>
                    <description><![CDATA[Together AI provider for Umbraco AI]]></description>
                    <pubDate>Thu, 07 May 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.ai.fireworksai</guid>
                    <title>Umbraco.AI.FireworksAI</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.ai.fireworksai</link>
                    <description><![CDATA[Fireworks AI provider for Umbraco AI]]></description>
                    <pubDate>Thu, 07 May 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.ai.huggingface</guid>
                    <title>Umbraco.AI.HuggingFace</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.ai.huggingface</link>
                    <description><![CDATA[Hugging Face Inference Providers integration for Umbraco AI]]></description>
                    <pubDate>Thu, 07 May 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.ai.deepseek</guid>
                    <title>Umbraco.AI.DeepSeek</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.ai.deepseek</link>
                    <description><![CDATA[DeepSeek provider for Umbraco AI]]></description>
                    <pubDate>Thu, 07 May 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://forum.umbraco.com/t/god-mode-v17-finally/7983</guid>
                    <title>God Mode v17 now available</title>
                    <link>https://forum.umbraco.com/t/god-mode-v17-finally/7983</link>
                    <description><![CDATA[God Mode v17 - finally! - Umbraco community forum]]></description>
                    <pubDate>Wed, 06 May 2026 12:37:11 Z</pubDate>
                        <category>community</category>
                        <category>forum</category>
                </item>
                <item>
                    <guid>https://kjac.dev/posts/personalisation-groups-as-segments/</guid>
                    <title>Personalisation Groups as segments</title>
                    <link>https://kjac.dev/posts/personalisation-groups-as-segments/</link>
                    <description><![CDATA[Using the Personalisation Groups package to power segments in Umbraco.]]></description>
                    <pubDate>Wed, 06 May 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://dev.to/luukpeters/advanced-permissions-for-umbraco-advanced-control-for-complex-scenarios-3fk3</guid>
                    <title>New package: Advanced User Group Permissions for Umbraco</title>
                    <link>https://dev.to/luukpeters/advanced-permissions-for-umbraco-advanced-control-for-complex-scenarios-3fk3</link>
                    <description><![CDATA[&lt;p&gt;&lt;em&gt;Quick note: I write these blogs myself, AI only redacts them.&lt;/em&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I&#x27;m excited to announce that I just released my very first open source Umbraco community package: &lt;strong&gt;Advanced Permissions for Umbraco&lt;/strong&gt;! In this post, I&#x27;ll explain why I created this package, what it adds to Umbraco&#x27;s permission system, and when you&#x27;d want to use it.&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  Why This Package Exists&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;I&#x27;ve been working with Umbraco since version 4, mostly in an agency context where projects often involve multiple editors, multiple user groups, and more complex content structures. That experience shaped what I value: features that give teams enough control without making day-to-day editing harder.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I wrote about these scenarios in a &lt;a href=&quot;https://github.com/umbraco/Umbraco-CMS/discussions/18018&quot; rel=&quot;noopener noreferrer&quot;&gt;GitHub discussion&lt;/a&gt; a while back. The current permission system works fine for many use cases, but I do think it becomes too limited once projects grow in complexity. In my opinion, this is an area where Umbraco could &#x2014; and should &#x2014; offer more flexibility.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;For now, this package is my attempt to solve that problem in a practical way. Advanced Permissions for Umbraco is designed for situations where the built-in permission model does not give you enough control.&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  The Current Permission System (In a Nutshell)&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;To really understand the benefits of Advanced Permissions, you first need to understand the default Umbraco permission system. Here&#x27;s how it works:&lt;/p&gt;&#xA;&#xA;&lt;p&gt;You assign default permissions to a User Group by toggling a list of verbs: &lt;em&gt;Create&lt;/em&gt;, &lt;em&gt;Delete&lt;/em&gt;, &lt;em&gt;Cultures and Hostnames&lt;/em&gt;, &lt;em&gt;Publish&lt;/em&gt;, and so on. Users with that group inherit those permissions.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&quot;https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffkbkzzf4dqcsw2307ji8.png&quot; class=&quot;article-body-image-wrapper&quot;&gt;&lt;img src=&quot;https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffkbkzzf4dqcsw2307ji8.png&quot; alt=&quot;Umbraco&#x27;s default permission system&quot; width=&quot;800&quot; height=&quot;500&quot;&gt;&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;You can also override these permissions on specific nodes, and those overrides apply to that node and all its descendants. It&#x27;s straightforward and handles most workflows well.&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  Where It Reaches Its Limits&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;h3&gt;&#xA;  &#xA;  &#xA;  Grant Types and Inheritance&#xA;&lt;/h3&gt;&#xA;&#xA;&lt;p&gt;In Umbraco, you set default permissions on a User Group, and then you can override those on specific nodes. But here&#x27;s the catch&#x2014;when you override permissions on a node, those node-specific permissions completely replace the defaults. There&#x27;s no inheritance.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;So if you want to change just one permission on a node (say, disallow Delete), you have to specify every single permission at that node level. You can&#x27;t say &quot;inherit everything from the default and only change this one thing.&quot; You end up copying all the default permissions to the node level just to tweak one, which is error-prone and a maintenance nightmare. &lt;/p&gt;&#xA;&#xA;&lt;p&gt;And because permissions are just toggles&#x2014;allow (checked) or deny (unchecked)&#x2014;there&#x27;s really only &quot;allow&quot; and a sort of implicit &quot;not-allow.&quot; There&#x27;s no way to explicitly deny something. This matters when you have multiple User Groups on a single user: all their permissions just stack up. You can only gain permissions, never restrict them.&lt;/p&gt;&#xA;&#xA;&lt;h3&gt;&#xA;  &#xA;  &#xA;  Scope&#xA;&lt;/h3&gt;&#xA;&#xA;&lt;p&gt;Node permissions always apply to a node and its descendants. You can&#x27;t set permissions on just the node itself, or just on descendants.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Take an employee directory: an overview page with employee pages underneath. Ideally, you&#x27;d want editors to leave the overview page alone but be able to delete individual employee pages as they leave. The current system doesn&#x27;t support that directly.&lt;/p&gt;&#xA;&#xA;&lt;h3&gt;&#xA;  &#xA;  &#xA;  Multiple User Groups&#xA;&lt;/h3&gt;&#xA;&#xA;&lt;p&gt;When a user has multiple groups, their effective permissions are the combined list of everything allowed across those groups. There&#x27;s no way to say &quot;this group can do X, but that specific group cannot delete content.&quot; You get the union of all their permissions.&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  What Advanced Permissions Adds&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;The package introduces three capabilities for when you need more control:&lt;/p&gt;&#xA;&#xA;&lt;h3&gt;&#xA;  &#xA;  &#xA;  Three Grant Types (Allow, Deny, Inherit)&#xA;&lt;/h3&gt;&#xA;&#xA;&lt;p&gt;Instead of just allow/deny, you get:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;strong&gt;Allow&lt;/strong&gt;: explicitly permit something&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;strong&gt;Deny&lt;/strong&gt;: explicitly forbid something&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;strong&gt;Inherit&lt;/strong&gt;: use whatever the ancestor nodes specifies&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&quot;https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxjo7zq8gf19tk6ae9g9b.png&quot; class=&quot;article-body-image-wrapper&quot;&gt;&lt;img src=&quot;https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxjo7zq8gf19tk6ae9g9b.png&quot; alt=&quot; &quot; width=&quot;533&quot; height=&quot;480&quot;&gt;&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;This means you only need to set the permissions you want to change and let everything else inherit from above. No more duplicating every permission just to tweak one.&lt;/p&gt;&#xA;&#xA;&lt;h3&gt;&#xA;  &#xA;  &#xA;  Flexible Scopes&#xA;&lt;/h3&gt;&#xA;&#xA;&lt;p&gt;Choose where permissions apply:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;strong&gt;Node &#x2B; Descendants&lt;/strong&gt; (the standard Umbraco behavior)&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;strong&gt;Node Only&lt;/strong&gt; (children inherit from ancestors above)&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;strong&gt;Descendants Only&lt;/strong&gt; (the node itself isn&#x27;t affected)&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;You can combine node-only and descendants-only permissions on the same node to set different rules for a parent and its children.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&quot;https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwe2s1ftb17h24rx2af5n.png&quot; class=&quot;article-body-image-wrapper&quot;&gt;&lt;img src=&quot;https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwe2s1ftb17h24rx2af5n.png&quot; alt=&quot; &quot; width=&quot;532&quot; height=&quot;483&quot;&gt;&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;h3&gt;&#xA;  &#xA;  &#xA;  Smart Permission Resolution&#xA;&lt;/h3&gt;&#xA;&#xA;&lt;p&gt;Advanced Permissions includes a resolver that calculates your actual permissions based on priority:&lt;/p&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Explicit deny (takes precedence)&lt;/li&gt;&#xA;&lt;li&gt;Explicit allow&lt;/li&gt;&#xA;&lt;li&gt;Implicit deny&lt;/li&gt;&#xA;&lt;li&gt;Implicit allow&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;p&gt;It handles multiple User Groups intelligently across all of them.&lt;/p&gt;&#xA;&#xA;&lt;h3&gt;&#xA;  &#xA;  &#xA;  Apply Permissions to Everyone&#xA;&lt;/h3&gt;&#xA;&#xA;&lt;p&gt;There&#x27;s a virtual &quot;All Users&quot; group for permissions that should apply to everyone. Useful for nodes that should never be deleted, for example. It works like any other group from the resolver&#x27;s perspective.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&quot;https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkbflq4le9ck1t4blfntd.png&quot; class=&quot;article-body-image-wrapper&quot;&gt;&lt;img src=&quot;https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkbflq4le9ck1t4blfntd.png&quot; alt=&quot; &quot; width=&quot;800&quot; height=&quot;178&quot;&gt;&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;h3&gt;&#xA;  &#xA;  &#xA;  The Access Viewer&#xA;&lt;/h3&gt;&#xA;&#xA;&lt;p&gt;To understand your actual permissions when things get complex, there&#x27;s an Access Viewer that shows your effective permissions for any user or group. Click on any permission and see the resolver chain that determined it.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&quot;https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2uymz3li28lo21sqfg15.png&quot; class=&quot;article-body-image-wrapper&quot;&gt;&lt;img src=&quot;https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2uymz3li28lo21sqfg15.png&quot; alt=&quot; &quot; width=&quot;800&quot; height=&quot;433&quot;&gt;&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  When You&#x27;d Use This&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;You&#x27;d reach for Advanced Permissions when the built-in permission model starts to feel too restrictive&#x2014;multiple teams with overlapping responsibilities, permissions that need to vary significantly across your content tree, or content structures that don&#x27;t fit neatly into the standard model.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;For simple scenarios, Umbraco&#x27;s built-in permissions may be enough. But when you need more control over how permissions are inherited, combined, allowed, or denied, Advanced Permissions gives you a more flexible model to work with.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;You can find the package on the &lt;a href=&quot;https://marketplace.umbraco.com/package/umbraco.community.advancedpermissions&quot; rel=&quot;noopener noreferrer&quot;&gt;Umbraco marketplace&lt;/a&gt; today!&lt;/p&gt;]]></description>
                    <pubDate>Tue, 05 May 2026 20:56:44 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://skrift.io/issues/#127</guid>
                    <title>Skrift Issue #127</title>
                    <link>https://skrift.io/issues/#127</link>
                    <description><![CDATA[Featuring guest posts by Dean Leigh on &quot;Document Everything Everywhere All At Once&quot; and Allen Smith on &quot;Deconstructing Umbraco Compose&quot;]]></description>
                    <pubDate>Tue, 05 May 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                        <category>skrift</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/ai12z.umbraco.widgets</guid>
                    <title>Ai12z.Umbraco.Widgets</title>
                    <link>https://marketplace.umbraco.com/package/ai12z.umbraco.widgets</link>
                    <description><![CDATA[Drag-and-drop ai12z widgets for Umbraco CMS &#x2014; chatbot, CTA search, knowledge box, search results, forms, and containers. Renders native Umbraco Block List elements that emit ai12z web component tags.]]></description>
                    <pubDate>Tue, 05 May 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://github.com/Ambertvu/Umbraco.Community.AdminOnly</guid>
                    <title>Umbraco.Community.AdminOnly</title>
                    <link>https://github.com/Ambertvu/Umbraco.Community.AdminOnly</link>
                    <description><![CDATA[https://github.com/Ambertvu/Umbraco.Community.AdminOnly&#xA;&#xA;Another new package!&#xA;AdminOnly lets administrators hide document types, tabs and properties from everyone who isn&#x27;t an admin &#x2014; without touching user groups, permissions or document type structure. Editors see only what&#x27;s relevant to their work; admins keep the full picture, with a &#x1F512; indicator next to every hidden item.&#xA;&#xA;Heads up &#x2014; this is a backoffice UX layer, not server-side authorization. Hidden items are removed from the UI, but the underlying Umbraco APIs are untouched. A determined user with developer tools can still reach hidden content.]]></description>
                    <pubDate>Mon, 04 May 2026 14:14:48 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                </item>
                <item>
                    <guid>https://owaincodes.uksouth01.umbraco.io/blog/2026/may/a-weekend-without-internet-access/</guid>
                    <title>A weekend without internet access</title>
                    <link>https://owaincodes.uksouth01.umbraco.io/blog/2026/may/a-weekend-without-internet-access/</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Mon, 04 May 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://33b6c16b-3387-4d68-9090-4cb1f20ea7b3.azurewebsites.nethttps://owain.codes/blog/2026/may/a-weekend-without-internet-access/</guid>
                    <title>A weekend without internet access</title>
                    <link>https://33b6c16b-3387-4d68-9090-4cb1f20ea7b3.azurewebsites.nethttps://owain.codes/blog/2026/may/a-weekend-without-internet-access/</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Mon, 04 May 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://owain.codes/blog/2026/may/a-weekend-without-internet-access/</guid>
                    <title>A weekend without internet access</title>
                    <link>https://owain.codes/blog/2026/may/a-weekend-without-internet-access/</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Mon, 04 May 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://skttl.dev/blog/umbraco-cloud-fetch-database-and-media/</guid>
                    <title>Two Umbraco Cloud CLI spinoffs: fetch DB and media into your local dev</title>
                    <link>https://skttl.dev/blog/umbraco-cloud-fetch-database-and-media/</link>
                    <description><![CDATA[Two wizard CLIs that pull a fresh database and media folder from Umbraco Cloud straight into your local dev project - spinoffs from the archiver, useful on their own.]]></description>
                    <pubDate>Mon, 04 May 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://www.dynamicdave.nl/blog/accessibility-on-the-web/</guid>
                    <title>Accessibility on the Web: Why It&#x27;s Mission-Critical, Not Just Another Task to Tick Off</title>
                    <link>https://www.dynamicdave.nl/blog/accessibility-on-the-web/</link>
                    <description><![CDATA[Let&#x2019;s be honest&#x2014;most teams know that accessibility matters. Everybody nods along when it comes up. But as deadlines creep closer and pressure ramps up, accessibility quietly slides out of focus, landing in the &#x201C;we&#x2019;ll get to it later&#x201D; pile. And we all know how rare it is to dig into that pile once the release goes live.Ignoring accessibility during development is a costly shortcut. You can&#x2019;t tack it on at the last minute and hope for a smooth outcome. It&#x2019;s more like the foundation&#x2014;get it wrong and everything on top is unstable. Accessibility shapes how you organize your content, how you design and build components, and how users actually use your site. Put it off, and you&#x2019;re not just risking some awkward code rewrites later. You&#x2019;re almost guaranteed to exclude real people&#x2014;people who just want to use your site like anyone else.If you&#x2019;re working with Umbraco 17, you&#x2019;ve got a solid foundation for accessibility. The platform itself doesn&#x2019;t hold you back. But it&#x2019;s your choices&#x2014;the way you structure content and the standards you enforce&#x2014;that make or break the user experience.]]></description>
                    <pubDate>Sun, 03 May 2026 22:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://bsky.app/profile/owain.codes/post/3mkwtz5dbwt24</guid>
                    <title>Ideas wanted for h5yr.com</title>
                    <link>https://bsky.app/profile/owain.codes/post/3mkwtz5dbwt24</link>
                    <description><![CDATA[Calling all #Umbraco friends. &#xA;&#xA;Im relaunching h5yr.com and I want all your ideas on what features we can build for the site. &#xA;&#xA;Add your ideas to the issues tracker in github.com/H5YR/High5Yo...&#xA;&#xA;Then together, as a community, we&#x27;ll build them!&#xA;&#xA;]]></description>
                    <pubDate>Sun, 03 May 2026 09:37:39 Z</pubDate>
                        <category>community</category>
                        <category>bluesky</category>
                        <category>social</category>
                </item>
                <item>
                    <guid>https://www.enkelmedia.se/blogg/2026/5/1/umbraco-member-thrown-out-after-changing-password?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=rss</guid>
                    <title>Umbraco Member thrown out after changing password</title>
                    <link>https://www.enkelmedia.se/blogg/2026/5/1/umbraco-member-thrown-out-after-changing-password?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=rss</link>
                    <description><![CDATA[I&#x27;m working with a migration of the website for my Umbraco-package Newsletter Studio, from Umbraco 8 to Umbraco 17.&#xA;I use Umbraco Members to allow customers to login and manage their licenses, update information and download receipts.&#xA;New password = Member logged out&#xA;When I was working on a feature to allow customers to change password, I noticed that I kept getting thrown out from the logged in area of the website after changing the password.&#xA;The Member was throw out both:&#xA;&#xA;When they change password them selfs&#xA;When the password was changed in from the backoffice&#xA;&#xA;I searched around for this, and it turns out that this is security feature.&#xA;Umbraco has introduce settings around concurrent logins both for Users and Members, in appsettings.json one can configure these&#xA;&amp;#xD;&#xA;&quot;Umbraco&quot;: {&#xA;    &quot;CMS&quot;: {      &#xA;        &quot;Security&quot;: {&#xA;            &quot;AllowConcurrentLogins&quot;: false&#xA;            &quot;MemberAllowConcurrentLogins&quot;: false&#xA;        }&#xA;    }&#xA;}&amp;#xD;&#xA;&amp;#xD;&#xA;&amp;#xD;&#xA;&#xA;According to the documentation, MemberAllowConcurrentLogins will fallback to the value of AllowConcurrentLogins, which is set to false by default.&#xA;What happened?&#xA;When the user changed the password, it looked like a new login, since this was not allowed the user was thrown out.&#xA;There is two ways around this, one could refresh the users login cookie by calling _memberSignInManager.SignInAsync() after the password change.&#xA;&amp;#xD;&#xA;var currentMember = await _memberManager.GetCurrentMemberAsync();&#xA;&#xA;var currentPasswordIsValid = await _memberManager.ValidateCredentialsAsync(currentMember.UserName!, model.CurrentPassword!);&#xA;if (!currentPasswordIsValid)&#xA;{&#xA;    return Error();&#xA;}&#xA;&#xA;var changePasswordResult = await _memberManager.ChangePasswordAsync(&#xA;    currentMember,&#xA;    model.CurrentPassword!,&#xA;    model.NewPassword!);&#xA;&#xA;if (!changePasswordResult.Succeeded)&#xA;{&#xA;    return Error();&#xA;}&#xA;&#xA;// Refresh member authentication cookie&#xA;await _memberSignInManager.SignInAsync(currentMember, true, &quot;&quot;);&amp;#xD;&#xA;&amp;#xD;&#xA;&amp;#xD;&#xA;&#xA;&#xA0;Or, one could set AllowConcurrentLogins to true.]]></description>
                    <pubDate>Fri, 01 May 2026 10:59:59 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://codeshare.co.uk/blog/how-i-used-the-new-umbraco-search-on-my-website/</guid>
                    <title>How I used the new Umbraco Search on my website</title>
                    <link>https://codeshare.co.uk/blog/how-i-used-the-new-umbraco-search-on-my-website/</link>
                    <description><![CDATA[Discover how I added powerful search to my blog with category filters and smart sorting. Real-world lessons from building search with Umbraco&amp;#x27;s new platform.]]></description>
                    <pubDate>Fri, 01 May 2026 10:30:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.advancedpermissions</guid>
                    <title>Umbraco.Community.AdvancedPermissions</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.advancedpermissions</link>
                    <description><![CDATA[Fine-grained permission management for Umbraco that extends the built-in permission system with the controls it lacks: explicit Allow and Deny entries, per-entry scope control (This Node Only, This Node and Descendants, Descendants Only), an All Users Group that applies to every user, and a full reasoning chain that explains why each permission was granted or denied.&#xA;&#xA;Got a critical node that must never be deleted? Set an explicit Deny for Delete on that node for the All Users Group. From that point on, the node cannot be deleted by anyone, from any user group, under any circumstances. An explicit Deny is absolute: nothing overrides it, not an inherited Allow, not an explicit Allow from another user group on the same node. The only way to lift the lock is to remove or edit that one entry. The same pattern works for any permission on any node: lock unpublishing on landing pages, block edits to integration nodes, enforce any other global safety rule.&#xA;&#xA;Adds two menu items to the Users section of the backoffice: a Permissions Editor for managing entries per user group across the content tree, and an Access Viewer for inspecting effective permissions with full reasoning. On first boot the package imports the permissions from your existing user groups automatically, so your current security setup carries over without any manual migration. New user groups created later are seeded the same way.]]></description>
                    <pubDate>Fri, 01 May 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://www.linkedin.com/posts/adamshallcross_so-like-london-buses-it-seems-my-mind-works-ugcPost-7455570629501734912-4wP7?utm_source=share&amp;utm_medium=member_ios&amp;rcm=ACoAAABj9KwBjr581HKBv-M3TbQu69Ia79rmfPw</guid>
                    <title>Introducing LlmsTxt.Umbraco</title>
                    <link>https://www.linkedin.com/posts/adamshallcross_so-like-london-buses-it-seems-my-mind-works-ugcPost-7455570629501734912-4wP7?utm_source=share&amp;utm_medium=member_ios&amp;rcm=ACoAAABj9KwBjr581HKBv-M3TbQu69Ia79rmfPw</link>
                    <description><![CDATA[Untitled: https://www.linkedin.com/posts/adamshallcross_so-like-london-buses-it-seems-my-mind-works-ugcPost-7455570629501734912-4wP7?utm_source=share&amp;utm_medium=member_ios&amp;rcm=ACoAAABj9KwBjr581HKBv-M3TbQu69Ia79rmfPw&#xA;&#xA;Sent from my iPhone]]></description>
                    <pubDate>Thu, 30 Apr 2026 11:08:48 Z</pubDate>
                        <category>social</category>
                        <category>linkedin</category>
                        <category>community</category>
                </item>
                <item>
                    <guid>https://github.com/umbraco/Announcements/issues/32</guid>
                    <title>[Breaking change]: Replace `Swashbuckle.AspNetCore` with `Microsoft.AspNetCore.OpenApi` for Open API document generation</title>
                    <link>https://github.com/umbraco/Announcements/issues/32</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Wed, 29 Apr 2026 13:19:40 Z</pubDate>
                        <category>hq</category>
                        <category>announcement</category>
                </item>
                <item>
                    <guid>https://www.proworks.com/blog/archive/umbraco-ai-page-evaluator/</guid>
                    <title>Catch Weak Content Before It Goes Live with ProWorks Umbraco.AI Page Evaluator</title>
                    <link>https://www.proworks.com/blog/archive/umbraco-ai-page-evaluator/</link>
                    <description><![CDATA[&lt;p&gt;In this day and age, its more important than ever to keep your website content clear, consistent, and on brand. AI infers what your organization does from what it reads on your website and, yes, it reads ALL of your content. Couple this with the rise of AI tools used to outline, write, and enhance marketing content, the risk of publishing AI slop (or even inaccurate information) is high. This is where the &lt;a rel=&quot;noopener&quot; type=&quot;external&quot; href=&quot;https://github.com/ProWorksCorporation/ProWorks-Umbraco.AI-Page-Evaluator&quot; target=&quot;_blank&quot; title=&quot;ProWorks Umbraco.AI Page Evaluator&quot;&gt;ProWorks Umbraco.AI Page Evaluator&lt;/a&gt; shines.&lt;/p&gt;&#xA;&lt;h2&gt;What Is AI-Powered Page Evaluation?&lt;/h2&gt;&#xA;&lt;p&gt;AI-powered page evaluation uses a large language model (LLM) to analyze your page content and return structured feedback on key page indicators.&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;A &lt;strong&gt;landing page&lt;/strong&gt; can be evaluated and scored for clarity, messaging strength, objection handling, message hierarchy, and the call to action.&lt;/li&gt;&#xA;&lt;li&gt;A standard &lt;strong&gt;content page&lt;/strong&gt; can be evaluated on SEO performance, AEO/GEO performance, and accessibility compliance.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;All pages&lt;/strong&gt; can be evaluated based on brand guidelines, brand voice, and how it supports the organization&#x27;s marketing strategy.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2&gt;What is ProWorks Umbraco.AI Page Evaluator (AI Page Evaluator)?&lt;/h2&gt;&#xA;&lt;p&gt;Our AI Page Evaluator is an open-source add-on to the &lt;a rel=&quot;noopener&quot; type=&quot;external&quot; href=&quot;https://github.com/umbraco/Umbraco.AI/&quot; target=&quot;_blank&quot; title=&quot;Umbraco.AI&quot;&gt;Umbraco.AI&lt;/a&gt; framework, which adds a back-office Evaluate Page button you can simply click on to send the page&#x27;s content to an AI model and return a structured quality report directly inside the back-office, including scored checks, warnings, and actionable suggestions.&lt;/p&gt;&#xA;&lt;p&gt;&lt;img style=&quot;display: block; margin-left: auto; margin-right: auto;&quot; src=&quot;https://www.proworks.com/media/uzfpov4h/screenshot-2026-04-14-162237.png&quot; alt=&quot;Page Evaluator Scoring Report&quot; width=&quot;900&quot; height=&quot;490&quot;&gt;&lt;/p&gt;&#xA;&lt;p&gt;This AI Page Evaluator started because we had a need to evaluate our own Landing Pages and Blog Posts on a rubric to verify content was clear, structured well, and communicated our intent. We had been doing this QA outside of Umbraco and preferred something that lived inside the editorial workflow and was frictionless for content editors to use.&lt;/p&gt;&#xA;&lt;p&gt;ProWorks Umbraco.AI Page Evaluator works with&#xA0;&lt;a rel=&quot;noopener&quot; type=&quot;external&quot; href=&quot;https://umbraco.com/&quot; target=&quot;_blank&quot; title=&quot;Umbraco&quot;&gt;Umbraco&lt;/a&gt; 17.x&#xA0;in combination with the Umbraco.AI official package.&lt;/p&gt;&#xA;&lt;h2&gt;How To Get Started&lt;/h2&gt;&#xA;&lt;p&gt;The install is super-fast, and if you already use Umbraco.AI on Umbraco 17, configuration is fast as well.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Requirements:&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Umbraco 17.3&#x2B;&lt;/li&gt;&#xA;&lt;li&gt;Umbraco.AI&lt;/li&gt;&#xA;&lt;li&gt;.Net 10&#x2B;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h4&gt;Installation&lt;/h4&gt;&#xA;&lt;p&gt;Use NuGet to install AI Page Evaluator for your Umbraco project.&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt; &amp;gt; dotnet add package ProWorks.Umbraco.AI.PageEvaluator&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;Or search for &lt;strong&gt;ProWorks.Umbraco.AI.PageEvaluator&lt;/strong&gt; in the NuGet Package Manager in Visual Studio.&lt;/p&gt;&#xA;&lt;p&gt;Package page: &lt;a href=&quot;https://www.nuget.org/packages/ProWorks.Umbraco.AI.PageEvaluator&quot;&gt;https://www.nuget.org/packages/ProWorks.Umbraco.AI.PageEvaluator&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;Then build the project, run the website, and login to the back-office.&lt;/p&gt;&#xA;&lt;h4&gt;Configuration&lt;/h4&gt;&#xA;&lt;p&gt;In the back-office, go to the &quot;AI&quot; section. Verify you have a Connection to an AI API and a Profile created that uses the Connection that you want to use.&lt;/p&gt;&#xA;&lt;p&gt;Now go to the Page Evaluator area under Add-ons. Click the &quot;Create New&quot; button and follow the steps below:&lt;br&gt;&lt;br&gt;&lt;img style=&quot;display: block; margin-left: auto; margin-right: auto;&quot; src=&quot;https://www.proworks.com/media/3ibaot4t/screenshot-2026-04-28-165602.png&quot; alt=&quot;Configuration Area&quot; width=&quot;889&quot; height=&quot;528&quot;&gt;&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Fill in the &lt;strong&gt;Name &lt;/strong&gt;and &lt;strong&gt;Description&#xA0;&lt;/strong&gt;&lt;/li&gt;&#xA;&lt;li&gt;Select a &lt;strong&gt;Document Type&lt;/strong&gt; to apply the Page Evaluator to. Simply start typing a DocType name and choose the item from the list.&lt;/li&gt;&#xA;&lt;li&gt;Select the &lt;strong&gt;AI Profile&lt;/strong&gt; to use for this Page Evaluator. Select the &lt;strong&gt;AI Context&lt;/strong&gt; if desired.&lt;br&gt;&lt;br&gt;&lt;img style=&quot;display: block; margin-left: auto; margin-right: auto;&quot; src=&quot;https://www.proworks.com/media/1vabd3fl/screenshot-2026-04-28-165951.png&quot; alt=&quot;Configuration-1&quot; width=&quot;783&quot; height=&quot;578&quot;&gt;&lt;/li&gt;&#xA;&lt;li&gt;Review the &lt;strong&gt;Properties to Evaluate&lt;/strong&gt; and remove any properties that aren&#x27;t important for the type of Page Evaluation you are setting up.&lt;br&gt;&lt;br&gt;&lt;img style=&quot;display: block; margin-left: auto; margin-right: auto;&quot; src=&quot;https://www.proworks.com/media/psddlqul/screenshot-2026-04-28-170238.png&quot; alt=&quot;Properties to Evaluate&quot; width=&quot;666&quot; height=&quot;430&quot;&gt;&lt;/li&gt;&#xA;&lt;li&gt;Paste in the prompt you would like to use or open the &lt;strong&gt;Prompt Builder&lt;/strong&gt; to help guide you on building a prompt.&lt;br&gt;&lt;br&gt;&lt;img style=&quot;display: block; margin-left: auto; margin-right: auto;&quot; src=&quot;https://www.proworks.com/media/tifhcc2q/screenshot-2026-04-28-170336.png&quot; alt=&quot;Screenshot 2026-04-28 170336.png&quot; width=&quot;869&quot; height=&quot;346&quot;&gt;&lt;/li&gt;&#xA;&lt;li&gt;Be sure to &lt;strong&gt;Enable Scoring&lt;/strong&gt; if there are scoring values that will be a part of the prompt.&lt;br&gt;&lt;br&gt;&lt;img style=&quot;display: block; margin-left: auto; margin-right: auto;&quot; src=&quot;https://www.proworks.com/media/fvabbv1k/screenshot-2026-04-28-170829.png&quot; alt=&quot;Enable Scoring&quot; width=&quot;618&quot; height=&quot;110&quot;&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h4&gt;Test it Out&lt;/h4&gt;&#xA;&lt;p&gt;Go to the Content section. Find a page that is of the document type that you specified in the configuration.&#xA0; Press the &lt;strong&gt;Evaluate Page&lt;/strong&gt; button in the bottom right area of the back-office.&lt;/p&gt;&#xA;&lt;p&gt;&lt;img style=&quot;display: block; margin-left: auto; margin-right: auto;&quot; src=&quot;https://www.proworks.com/media/ueggilpw/umbraco-ai-page-evaluation.png&quot; alt=&quot;Umbraco.AI Page Evaluation&quot; width=&quot;542&quot; height=&quot;77&quot;&gt;&lt;/p&gt;&#xA;&lt;p&gt;Page properties will be sent to AI with your evaluation criteria. An evaluation report will display with recommendations, a list of items to review, and scoring (if enabled).&lt;/p&gt;&#xA;&lt;p&gt;The results are cached so that AI doesn&#x27;t have to run each time you want to view the report (save those tokens!). It will re-run the report if the page has been saved since either the last run or if the evaluation criteria has been updated..&lt;/p&gt;&#xA;&lt;p&gt;&lt;img style=&quot;display: block; margin-left: auto; margin-right: auto;&quot; src=&quot;https://www.proworks.com/media/0e5h2u5o/screenshot-2026-04-28-171542.png&quot; alt=&quot;ProWorks Page Evaluation Report&quot; width=&quot;1165&quot; height=&quot;634&quot;&gt;&lt;/p&gt;&#xA;&lt;h2&gt;Key Takeaways&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Content clarity is now a competitive factor and AI systems interpret your pages before many visitors do.&lt;/li&gt;&#xA;&lt;li&gt;ProWorks Umbraco.AI Page Evaluator brings structured, content quality feedback directly into the Umbraco editor.&lt;/li&gt;&#xA;&lt;li&gt;It&#x27;s open source, built by an Umbraco Platinum Partner, and available now on NuGet.&lt;/li&gt;&#xA;&lt;li&gt;Better content evaluation upstream means fewer post-launch surprises.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2&gt;Check it Out!&lt;/h2&gt;&#xA;&lt;p&gt;Try the plugin, open an issue, suggest a feature. It&#x27;s open source and we want to know how teams are using it.&lt;/p&gt;&#xA;&lt;p&gt;&lt;a style=&quot;color: #fff; background-image: none;&quot; rel=&quot;noopener&quot; type=&quot;external&quot; href=&quot;https://github.com/ProWorksCorporation/ProWorks-Umbraco.AI-Page-Evaluator&quot; target=&quot;_blank&quot; title=&quot;View the package on Github&quot; class=&quot;pw-button&quot; data-anchor=&quot;#section-footer&quot;&gt;View on Github&lt;/a&gt;&lt;/p&gt;&#xA;&lt;div&gt;&#xA;&lt;h2&gt;Need Help?&lt;/h2&gt;&#xA;&lt;p&gt;If you&#x27;d like help implementing this as part of a broader content quality initiative, or if you&#x27;re evaluating an Umbraco upgrade and want content quality to be part of that conversation, we&#x27;d love to talk.&lt;/p&gt;&#xA;&lt;p&gt;&lt;a style=&quot;color: #fff; background-image: none;&quot; type=&quot;external&quot; href=&quot;#section-footer&quot; title=&quot;Request an Initial Consultation&quot; class=&quot;pw-button&quot; data-anchor=&quot;#section-footer&quot;&gt;Schedule a Consultation&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/div&gt;&#xA;&lt;h2&gt;Frequently Asked Questions (FAQ)&lt;/h2&gt;&#xA;&lt;div id=&quot;faq-56aaba21fce947e7a6fc15711e8217cf&quot; class=&quot;accordion&quot;&gt;&#xA;&lt;div class=&quot;accordion-item&quot;&gt;&#xA;&lt;h4 class=&quot;accordion-header&quot;&gt;&lt;button class=&quot;accordion-button collapsed&quot; data-bs-toggle=&quot;collapse&quot; data-bs-target=&quot;#faq-item-39f1deabb1ac4f2a9990ea5d36668607&quot; aria-expanded=&quot;false&quot; aria-controls=&quot;faq-item-39f1deabb1ac4f2a9990ea5d36668607&quot;&gt; Does the plugin work with any AI provider, or only Claude / Anthropic? &lt;/button&gt;&lt;/h4&gt;&#xA;&lt;div id=&quot;faq-item-39f1deabb1ac4f2a9990ea5d36668607&quot; class=&quot;accordion-collapse collapse&quot;&gt;&#xA;&lt;div class=&quot;accordion-body&quot;&gt;&#xA;&lt;p&gt;It works with any AI provider configured in Umbraco.AI, including Anthropic Claude, OpenAI, and others. The plugin is provider-agnostic by design; you select the AI profile when setting up an evaluator configuration, so whichever model your team already has access to will work.&lt;/p&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&#xA;&lt;div class=&quot;accordion-item&quot;&gt;&#xA;&lt;h4 class=&quot;accordion-header&quot;&gt;&lt;button class=&quot;accordion-button collapsed&quot; data-bs-toggle=&quot;collapse&quot; data-bs-target=&quot;#faq-item-13a35cfe03f24500b5877141b4887768&quot; aria-expanded=&quot;false&quot; aria-controls=&quot;faq-item-13a35cfe03f24500b5877141b4887768&quot;&gt; What versions of Umbraco does it support? &lt;/button&gt;&lt;/h4&gt;&#xA;&lt;div id=&quot;faq-item-13a35cfe03f24500b5877141b4887768&quot; class=&quot;accordion-collapse collapse&quot;&gt;&#xA;&lt;div class=&quot;accordion-body&quot;&gt;&#xA;&lt;p&gt;The current release requires Umbraco CMS 17.3.x&#x2B;, Umbraco.AI 1.8.x&#x2B;, and .NET 10. If your site is on an earlier version of Umbraco, the plugin is not compatible yet. Support for additional versions may come in future releases.&lt;/p&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&#xA;&lt;div class=&quot;accordion-item&quot;&gt;&#xA;&lt;h4 class=&quot;accordion-header&quot;&gt;&lt;button class=&quot;accordion-button collapsed&quot; data-bs-toggle=&quot;collapse&quot; data-bs-target=&quot;#faq-item-ee7fc7bd0f594e0d98f3c22916f27bb4&quot; aria-expanded=&quot;false&quot; aria-controls=&quot;faq-item-ee7fc7bd0f594e0d98f3c22916f27bb4&quot;&gt; Does the plugin send my content to a third-party API? &lt;/button&gt;&lt;/h4&gt;&#xA;&lt;div id=&quot;faq-item-ee7fc7bd0f594e0d98f3c22916f27bb4&quot; class=&quot;accordion-collapse collapse&quot;&gt;&#xA;&lt;div class=&quot;accordion-body&quot;&gt;&#xA;&lt;p&gt;Yes, it sends page content to whichever AI provider you have configured in Umbraco.AI. Before sending, the plugin cleans the content: HTML tags are stripped and long property values are truncated to reduce token usage. If your organization has data sensitivity requirements, review your AI provider&#x27;s data handling policies before deploying. You can also use the property filtering feature to exclude specific fields from the evaluation entirely.&lt;/p&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&#xA;&lt;div class=&quot;accordion-item&quot;&gt;&#xA;&lt;h4 class=&quot;accordion-header&quot;&gt;&lt;button class=&quot;accordion-button collapsed&quot; data-bs-toggle=&quot;collapse&quot; data-bs-target=&quot;#faq-item-eaf3fd5658144d9fbeaefd8e82e38397&quot; aria-expanded=&quot;false&quot; aria-controls=&quot;faq-item-eaf3fd5658144d9fbeaefd8e82e38397&quot;&gt; Can I control which content gets sent to the AI? &lt;/button&gt;&lt;/h4&gt;&#xA;&lt;div id=&quot;faq-item-eaf3fd5658144d9fbeaefd8e82e38397&quot; class=&quot;accordion-collapse collapse&quot;&gt;&#xA;&lt;div class=&quot;accordion-body&quot;&gt;&#xA;&lt;p&gt;Yes. When setting up an evaluator configuration, you can select exactly which document type properties to include in the evaluation. Any properties you do not select are excluded from the AI call. This is useful both for keeping sensitive fields private and for reducing token usage on pages with large amounts of irrelevant content.&lt;/p&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&#xA;&lt;div class=&quot;accordion-item&quot;&gt;&#xA;&lt;h4 class=&quot;accordion-header&quot;&gt;&lt;button class=&quot;accordion-button collapsed&quot; data-bs-toggle=&quot;collapse&quot; data-bs-target=&quot;#faq-item-fd851378877c42f6aef7e6f10c536b3a&quot; aria-expanded=&quot;false&quot; aria-controls=&quot;faq-item-fd851378877c42f6aef7e6f10c536b3a&quot;&gt; Can I customize what the AI evaluates? &lt;/button&gt;&lt;/h4&gt;&#xA;&lt;div id=&quot;faq-item-fd851378877c42f6aef7e6f10c536b3a&quot; class=&quot;accordion-collapse collapse&quot;&gt;&#xA;&lt;div class=&quot;accordion-body&quot;&gt;&#xA;&lt;p&gt;Yes, this is one of the plugin&#x27;s core design principles. Each evaluator configuration uses a custom prompt you write for that specific document type. The Prompt Builder UI can auto-generate a starting prompt from your document type&#x27;s properties and a set of checklist categories, which you can then edit and refine. You can also attach a Context resource from Umbraco.AI to give the model additional background about your organization or brand.&lt;/p&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&#xA;&lt;div class=&quot;accordion-item&quot;&gt;&#xA;&lt;h4 class=&quot;accordion-header&quot;&gt;&lt;button class=&quot;accordion-button collapsed&quot; data-bs-toggle=&quot;collapse&quot; data-bs-target=&quot;#faq-item-905523a762f44aca8debd3d2de71521b&quot; aria-expanded=&quot;false&quot; aria-controls=&quot;faq-item-905523a762f44aca8debd3d2de71521b&quot;&gt; Is the plugin free? Are there any ongoing costs? &lt;/button&gt;&lt;/h4&gt;&#xA;&lt;div id=&quot;faq-item-905523a762f44aca8debd3d2de71521b&quot; class=&quot;accordion-collapse collapse&quot;&gt;&#xA;&lt;div class=&quot;accordion-body&quot;&gt;&#xA;&lt;p&gt;The plugin itself is free and open source under the MIT license. In addition, your AI provider&#x27;s API charges based on token usage. For most sites running on-demand evaluations, API costs are minimal.&lt;/p&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&#xA;&lt;div class=&quot;accordion-item&quot;&gt;&#xA;&lt;h4 class=&quot;accordion-header&quot;&gt;&lt;button class=&quot;accordion-button collapsed&quot; data-bs-toggle=&quot;collapse&quot; data-bs-target=&quot;#faq-item-f5a49851eeb34bba9eda56e46284ef6a&quot; aria-expanded=&quot;false&quot; aria-controls=&quot;faq-item-f5a49851eeb34bba9eda56e46284ef6a&quot;&gt;&#xA0;What&#x27;s the difference between this plugin and ProWorks&#x27; full AI content evaluation service? &lt;/button&gt;&lt;/h4&gt;&#xA;&lt;div id=&quot;faq-item-f5a49851eeb34bba9eda56e46284ef6a&quot; class=&quot;accordion-collapse collapse&quot;&gt;&#xA;&lt;div class=&quot;accordion-body&quot;&gt;&#xA;&lt;p&gt;The plugin evaluates individual pages on demand inside your Umbraco back office, using prompts you configure. It is a self-serve tool built for ongoing editorial quality control your team can run as part of a regular publishing workflow.&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&quot;/ai/&quot; title=&quot;ProWorks&#x27; site-wide AI Content Evaluation&quot;&gt;ProWorks&#x27; site-wide AI Content Evaluation&lt;/a&gt; service is a done-for-you engagement that analyzes how AI systems interpret your entire organization across all public content. It delivers an AI Perspective Report covering your inferred positioning, value propositions, audience signals, and content consistency. This plugin is a great starting point; the service is for teams who want the full picture across their whole site.&lt;/p&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;]]></description>
                    <pubDate>Wed, 29 Apr 2026 10:04:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://fa9976c2-5840-4a63-82ec-42e17b070c7d-1.azurewebsites.net/blog/archive/umbraco-ai-page-evaluator/</guid>
                    <title>Catch Weak Content Before It Goes Live with ProWorks Umbraco.AI Page Evaluator</title>
                    <link>https://fa9976c2-5840-4a63-82ec-42e17b070c7d-1.azurewebsites.net/blog/archive/umbraco-ai-page-evaluator/</link>
                    <description><![CDATA[&lt;p&gt;In this day and age, its more important than ever to keep your website content clear, consistent, and on brand. AI infers what your organization does from what it reads on your website and, yes, it reads ALL of your content. Couple this with the rise of AI tools used to outline, write, and enhance marketing content, the risk of publishing AI slop (or even inaccurate information) is high. This is where the &lt;a rel=&quot;noopener&quot; type=&quot;external&quot; href=&quot;https://github.com/ProWorksCorporation/ProWorks-Umbraco.AI-Page-Evaluator&quot; target=&quot;_blank&quot; title=&quot;ProWorks Umbraco.AI Page Evaluator&quot;&gt;ProWorks Umbraco.AI Page Evaluator&lt;/a&gt; shines.&lt;/p&gt;&#xA;&lt;h2&gt;What Is AI-Powered Page Evaluation?&lt;/h2&gt;&#xA;&lt;p&gt;AI-powered page evaluation uses a large language model (LLM) to analyze your page content and return structured feedback on key page indicators.&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;A &lt;strong&gt;landing page&lt;/strong&gt; can be evaluated and scored for clarity, messaging strength, objection handling, message hierarchy, and the call to action.&lt;/li&gt;&#xA;&lt;li&gt;A standard &lt;strong&gt;content page&lt;/strong&gt; can be evaluated on SEO performance, AEO/GEO performance, and accessibility compliance.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;All pages&lt;/strong&gt; can be evaluated based on brand guidelines, brand voice, and how it supports the organization&#x27;s marketing strategy.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2&gt;What is ProWorks Umbraco.AI Page Evaluator (AI Page Evaluator)?&lt;/h2&gt;&#xA;&lt;p&gt;Our AI Page Evaluator is an open-source add-on to the &lt;a rel=&quot;noopener&quot; type=&quot;external&quot; href=&quot;https://github.com/umbraco/Umbraco.AI/&quot; target=&quot;_blank&quot; title=&quot;Umbraco.AI&quot;&gt;Umbraco.AI&lt;/a&gt; framework, which adds a back-office Evaluate Page button you can simply click on to send the page&#x27;s content to an AI model and return a structured quality report directly inside the back-office, including scored checks, warnings, and actionable suggestions.&lt;/p&gt;&#xA;&lt;p&gt;&lt;img style=&quot;display: block; margin-left: auto; margin-right: auto;&quot; src=&quot;https://fa9976c2-5840-4a63-82ec-42e17b070c7d-1.azurewebsites.net/media/uzfpov4h/screenshot-2026-04-14-162237.png&quot; alt=&quot;Page Evaluator Scoring Report&quot; width=&quot;900&quot; height=&quot;490&quot;&gt;&lt;/p&gt;&#xA;&lt;p&gt;This AI Page Evaluator started because we had a need to evaluate our own Landing Pages and Blog Posts on a rubric to verify content was clear, structured well, and communicated our intent. We had been doing this QA outside of Umbraco and preferred something that lived inside the editorial workflow and was frictionless for content editors to use.&lt;/p&gt;&#xA;&lt;p&gt;ProWorks Umbraco.AI Page Evaluator works with&#xA0;&lt;a rel=&quot;noopener&quot; type=&quot;external&quot; href=&quot;https://umbraco.com/&quot; target=&quot;_blank&quot; title=&quot;Umbraco&quot;&gt;Umbraco&lt;/a&gt; 17.x&#xA0;in combination with the Umbraco.AI official package.&lt;/p&gt;&#xA;&lt;h2&gt;How To Get Started&lt;/h2&gt;&#xA;&lt;p&gt;The install is super-fast, and if you already use Umbraco.AI on Umbraco 17, configuration is fast as well.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Requirements:&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Umbraco 17.3&#x2B;&lt;/li&gt;&#xA;&lt;li&gt;Umbraco.AI&lt;/li&gt;&#xA;&lt;li&gt;.Net 10&#x2B;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h4&gt;Installation&lt;/h4&gt;&#xA;&lt;p&gt;Use NuGet to install AI Page Evaluator for your Umbraco project.&lt;/p&gt;&#xA;&lt;pre&gt;&lt;code&gt; &amp;gt; dotnet add package ProWorks.Umbraco.AI.PageEvaluator&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;Or search for &lt;strong&gt;ProWorks.Umbraco.AI.PageEvaluator&lt;/strong&gt; in the NuGet Package Manager in Visual Studio.&lt;/p&gt;&#xA;&lt;p&gt;Package page: &lt;a href=&quot;https://www.nuget.org/packages/ProWorks.Umbraco.AI.PageEvaluator&quot;&gt;https://www.nuget.org/packages/ProWorks.Umbraco.AI.PageEvaluator&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;Then build the project, run the website, and login to the back-office.&lt;/p&gt;&#xA;&lt;h4&gt;Configuration&lt;/h4&gt;&#xA;&lt;p&gt;In the back-office, go to the &quot;AI&quot; section. Verify you have a Connection to an AI API and a Profile created that uses the Connection that you want to use.&lt;/p&gt;&#xA;&lt;p&gt;Now go to the Page Evaluator area under Add-ons. Click the &quot;Create New&quot; button and follow the steps below:&lt;br&gt;&lt;br&gt;&lt;img style=&quot;display: block; margin-left: auto; margin-right: auto;&quot; src=&quot;https://fa9976c2-5840-4a63-82ec-42e17b070c7d-1.azurewebsites.net/media/3ibaot4t/screenshot-2026-04-28-165602.png&quot; alt=&quot;Configuration Area&quot; width=&quot;889&quot; height=&quot;528&quot;&gt;&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Fill in the &lt;strong&gt;Name &lt;/strong&gt;and &lt;strong&gt;Description&#xA0;&lt;/strong&gt;&lt;/li&gt;&#xA;&lt;li&gt;Select a &lt;strong&gt;Document Type&lt;/strong&gt; to apply the Page Evaluator to. Simply start typing a DocType name and choose the item from the list.&lt;/li&gt;&#xA;&lt;li&gt;Select the &lt;strong&gt;AI Profile&lt;/strong&gt; to use for this Page Evaluator. Select the &lt;strong&gt;AI Context&lt;/strong&gt; if desired.&lt;br&gt;&lt;br&gt;&lt;img style=&quot;display: block; margin-left: auto; margin-right: auto;&quot; src=&quot;https://fa9976c2-5840-4a63-82ec-42e17b070c7d-1.azurewebsites.net/media/1vabd3fl/screenshot-2026-04-28-165951.png&quot; alt=&quot;Configuration-1&quot; width=&quot;783&quot; height=&quot;578&quot;&gt;&lt;/li&gt;&#xA;&lt;li&gt;Review the &lt;strong&gt;Properties to Evaluate&lt;/strong&gt; and remove any properties that aren&#x27;t important for the type of Page Evaluation you are setting up.&lt;br&gt;&lt;br&gt;&lt;img style=&quot;display: block; margin-left: auto; margin-right: auto;&quot; src=&quot;https://fa9976c2-5840-4a63-82ec-42e17b070c7d-1.azurewebsites.net/media/psddlqul/screenshot-2026-04-28-170238.png&quot; alt=&quot;Properties to Evaluate&quot; width=&quot;666&quot; height=&quot;430&quot;&gt;&lt;/li&gt;&#xA;&lt;li&gt;Paste in the prompt you would like to use or open the &lt;strong&gt;Prompt Builder&lt;/strong&gt; to help guide you on building a prompt.&lt;br&gt;&lt;br&gt;&lt;img style=&quot;display: block; margin-left: auto; margin-right: auto;&quot; src=&quot;https://fa9976c2-5840-4a63-82ec-42e17b070c7d-1.azurewebsites.net/media/tifhcc2q/screenshot-2026-04-28-170336.png&quot; alt=&quot;Screenshot 2026-04-28 170336.png&quot; width=&quot;869&quot; height=&quot;346&quot;&gt;&lt;/li&gt;&#xA;&lt;li&gt;Be sure to &lt;strong&gt;Enable Scoring&lt;/strong&gt; if there are scoring values that will be a part of the prompt.&lt;br&gt;&lt;br&gt;&lt;img style=&quot;display: block; margin-left: auto; margin-right: auto;&quot; src=&quot;https://fa9976c2-5840-4a63-82ec-42e17b070c7d-1.azurewebsites.net/media/fvabbv1k/screenshot-2026-04-28-170829.png&quot; alt=&quot;Enable Scoring&quot; width=&quot;618&quot; height=&quot;110&quot;&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h4&gt;Test it Out&lt;/h4&gt;&#xA;&lt;p&gt;Go to the Content section. Find a page that is of the document type that you specified in the configuration.&#xA0; Press the &lt;strong&gt;Evaluate Page&lt;/strong&gt; button in the bottom right area of the back-office.&lt;/p&gt;&#xA;&lt;p&gt;&lt;img style=&quot;display: block; margin-left: auto; margin-right: auto;&quot; src=&quot;https://fa9976c2-5840-4a63-82ec-42e17b070c7d-1.azurewebsites.net/media/ueggilpw/umbraco-ai-page-evaluation.png&quot; alt=&quot;Umbraco.AI Page Evaluation&quot; width=&quot;542&quot; height=&quot;77&quot;&gt;&lt;/p&gt;&#xA;&lt;p&gt;Page properties will be sent to AI with your evaluation criteria. An evaluation report will display with recommendations, a list of items to review, and scoring (if enabled).&lt;/p&gt;&#xA;&lt;p&gt;The results are cached so that AI doesn&#x27;t have to run each time you want to view the report (save those tokens!). It will re-run the report if the page has been saved since either the last run or if the evaluation criteria has been updated..&lt;/p&gt;&#xA;&lt;p&gt;&lt;img style=&quot;display: block; margin-left: auto; margin-right: auto;&quot; src=&quot;https://fa9976c2-5840-4a63-82ec-42e17b070c7d-1.azurewebsites.net/media/0e5h2u5o/screenshot-2026-04-28-171542.png&quot; alt=&quot;ProWorks Page Evaluation Report&quot; width=&quot;1165&quot; height=&quot;634&quot;&gt;&lt;/p&gt;&#xA;&lt;h2&gt;Key Takeaways&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Content clarity is now a competitive factor and AI systems interpret your pages before many visitors do.&lt;/li&gt;&#xA;&lt;li&gt;ProWorks Umbraco.AI Page Evaluator brings structured, content quality feedback directly into the Umbraco editor.&lt;/li&gt;&#xA;&lt;li&gt;It&#x27;s open source, built by an Umbraco Platinum Partner, and available now on NuGet.&lt;/li&gt;&#xA;&lt;li&gt;Better content evaluation upstream means fewer post-launch surprises.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2&gt;Check it Out!&lt;/h2&gt;&#xA;&lt;p&gt;Try the plugin, open an issue, suggest a feature. It&#x27;s open source and we want to know how teams are using it.&lt;/p&gt;&#xA;&lt;p&gt;&lt;a style=&quot;color: #fff; background-image: none;&quot; rel=&quot;noopener&quot; type=&quot;external&quot; href=&quot;https://github.com/ProWorksCorporation/ProWorks-Umbraco.AI-Page-Evaluator&quot; target=&quot;_blank&quot; title=&quot;View the package on Github&quot; class=&quot;pw-button&quot; data-anchor=&quot;#section-footer&quot;&gt;View on Github&lt;/a&gt;&lt;/p&gt;&#xA;&lt;div&gt;&#xA;&lt;h2&gt;Need Help?&lt;/h2&gt;&#xA;&lt;p&gt;If you&#x27;d like help implementing this as part of a broader content quality initiative, or if you&#x27;re evaluating an Umbraco upgrade and want content quality to be part of that conversation, we&#x27;d love to talk.&lt;/p&gt;&#xA;&lt;p&gt;&lt;a style=&quot;color: #fff; background-image: none;&quot; type=&quot;external&quot; href=&quot;#section-footer&quot; title=&quot;Request an Initial Consultation&quot; class=&quot;pw-button&quot; data-anchor=&quot;#section-footer&quot;&gt;Schedule a Consultation&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/div&gt;&#xA;&lt;h2&gt;Frequently Asked Questions (FAQ)&lt;/h2&gt;&#xA;&lt;div id=&quot;faq-56aaba21fce947e7a6fc15711e8217cf&quot; class=&quot;accordion&quot;&gt;&#xA;&lt;div class=&quot;accordion-item&quot;&gt;&#xA;&lt;h4 class=&quot;accordion-header&quot;&gt;&lt;button class=&quot;accordion-button collapsed&quot; data-bs-toggle=&quot;collapse&quot; data-bs-target=&quot;#faq-item-39f1deabb1ac4f2a9990ea5d36668607&quot; aria-expanded=&quot;false&quot; aria-controls=&quot;faq-item-39f1deabb1ac4f2a9990ea5d36668607&quot;&gt; Does the plugin work with any AI provider, or only Claude / Anthropic? &lt;/button&gt;&lt;/h4&gt;&#xA;&lt;div id=&quot;faq-item-39f1deabb1ac4f2a9990ea5d36668607&quot; class=&quot;accordion-collapse collapse&quot;&gt;&#xA;&lt;div class=&quot;accordion-body&quot;&gt;&#xA;&lt;p&gt;It works with any AI provider configured in Umbraco.AI, including Anthropic Claude, OpenAI, and others. The plugin is provider-agnostic by design; you select the AI profile when setting up an evaluator configuration, so whichever model your team already has access to will work.&lt;/p&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&#xA;&lt;div class=&quot;accordion-item&quot;&gt;&#xA;&lt;h4 class=&quot;accordion-header&quot;&gt;&lt;button class=&quot;accordion-button collapsed&quot; data-bs-toggle=&quot;collapse&quot; data-bs-target=&quot;#faq-item-13a35cfe03f24500b5877141b4887768&quot; aria-expanded=&quot;false&quot; aria-controls=&quot;faq-item-13a35cfe03f24500b5877141b4887768&quot;&gt; What versions of Umbraco does it support? &lt;/button&gt;&lt;/h4&gt;&#xA;&lt;div id=&quot;faq-item-13a35cfe03f24500b5877141b4887768&quot; class=&quot;accordion-collapse collapse&quot;&gt;&#xA;&lt;div class=&quot;accordion-body&quot;&gt;&#xA;&lt;p&gt;The current release requires Umbraco CMS 17.3.x&#x2B;, Umbraco.AI 1.8.x&#x2B;, and .NET 10. If your site is on an earlier version of Umbraco, the plugin is not compatible yet. Support for additional versions may come in future releases.&lt;/p&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&#xA;&lt;div class=&quot;accordion-item&quot;&gt;&#xA;&lt;h4 class=&quot;accordion-header&quot;&gt;&lt;button class=&quot;accordion-button collapsed&quot; data-bs-toggle=&quot;collapse&quot; data-bs-target=&quot;#faq-item-ee7fc7bd0f594e0d98f3c22916f27bb4&quot; aria-expanded=&quot;false&quot; aria-controls=&quot;faq-item-ee7fc7bd0f594e0d98f3c22916f27bb4&quot;&gt; Does the plugin send my content to a third-party API? &lt;/button&gt;&lt;/h4&gt;&#xA;&lt;div id=&quot;faq-item-ee7fc7bd0f594e0d98f3c22916f27bb4&quot; class=&quot;accordion-collapse collapse&quot;&gt;&#xA;&lt;div class=&quot;accordion-body&quot;&gt;&#xA;&lt;p&gt;Yes, it sends page content to whichever AI provider you have configured in Umbraco.AI. Before sending, the plugin cleans the content: HTML tags are stripped and long property values are truncated to reduce token usage. If your organization has data sensitivity requirements, review your AI provider&#x27;s data handling policies before deploying. You can also use the property filtering feature to exclude specific fields from the evaluation entirely.&lt;/p&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&#xA;&lt;div class=&quot;accordion-item&quot;&gt;&#xA;&lt;h4 class=&quot;accordion-header&quot;&gt;&lt;button class=&quot;accordion-button collapsed&quot; data-bs-toggle=&quot;collapse&quot; data-bs-target=&quot;#faq-item-eaf3fd5658144d9fbeaefd8e82e38397&quot; aria-expanded=&quot;false&quot; aria-controls=&quot;faq-item-eaf3fd5658144d9fbeaefd8e82e38397&quot;&gt; Can I control which content gets sent to the AI? &lt;/button&gt;&lt;/h4&gt;&#xA;&lt;div id=&quot;faq-item-eaf3fd5658144d9fbeaefd8e82e38397&quot; class=&quot;accordion-collapse collapse&quot;&gt;&#xA;&lt;div class=&quot;accordion-body&quot;&gt;&#xA;&lt;p&gt;Yes. When setting up an evaluator configuration, you can select exactly which document type properties to include in the evaluation. Any properties you do not select are excluded from the AI call. This is useful both for keeping sensitive fields private and for reducing token usage on pages with large amounts of irrelevant content.&lt;/p&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&#xA;&lt;div class=&quot;accordion-item&quot;&gt;&#xA;&lt;h4 class=&quot;accordion-header&quot;&gt;&lt;button class=&quot;accordion-button collapsed&quot; data-bs-toggle=&quot;collapse&quot; data-bs-target=&quot;#faq-item-fd851378877c42f6aef7e6f10c536b3a&quot; aria-expanded=&quot;false&quot; aria-controls=&quot;faq-item-fd851378877c42f6aef7e6f10c536b3a&quot;&gt; Can I customize what the AI evaluates? &lt;/button&gt;&lt;/h4&gt;&#xA;&lt;div id=&quot;faq-item-fd851378877c42f6aef7e6f10c536b3a&quot; class=&quot;accordion-collapse collapse&quot;&gt;&#xA;&lt;div class=&quot;accordion-body&quot;&gt;&#xA;&lt;p&gt;Yes, this is one of the plugin&#x27;s core design principles. Each evaluator configuration uses a custom prompt you write for that specific document type. The Prompt Builder UI can auto-generate a starting prompt from your document type&#x27;s properties and a set of checklist categories, which you can then edit and refine. You can also attach a Context resource from Umbraco.AI to give the model additional background about your organization or brand.&lt;/p&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&#xA;&lt;div class=&quot;accordion-item&quot;&gt;&#xA;&lt;h4 class=&quot;accordion-header&quot;&gt;&lt;button class=&quot;accordion-button collapsed&quot; data-bs-toggle=&quot;collapse&quot; data-bs-target=&quot;#faq-item-905523a762f44aca8debd3d2de71521b&quot; aria-expanded=&quot;false&quot; aria-controls=&quot;faq-item-905523a762f44aca8debd3d2de71521b&quot;&gt; Is the plugin free? Are there any ongoing costs? &lt;/button&gt;&lt;/h4&gt;&#xA;&lt;div id=&quot;faq-item-905523a762f44aca8debd3d2de71521b&quot; class=&quot;accordion-collapse collapse&quot;&gt;&#xA;&lt;div class=&quot;accordion-body&quot;&gt;&#xA;&lt;p&gt;The plugin itself is free and open source under the MIT license. In addition, your AI provider&#x27;s API charges based on token usage. For most sites running on-demand evaluations, API costs are minimal.&lt;/p&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&#xA;&lt;div class=&quot;accordion-item&quot;&gt;&#xA;&lt;h4 class=&quot;accordion-header&quot;&gt;&lt;button class=&quot;accordion-button collapsed&quot; data-bs-toggle=&quot;collapse&quot; data-bs-target=&quot;#faq-item-f5a49851eeb34bba9eda56e46284ef6a&quot; aria-expanded=&quot;false&quot; aria-controls=&quot;faq-item-f5a49851eeb34bba9eda56e46284ef6a&quot;&gt;&#xA0;What&#x27;s the difference between this plugin and ProWorks&#x27; full AI content evaluation service? &lt;/button&gt;&lt;/h4&gt;&#xA;&lt;div id=&quot;faq-item-f5a49851eeb34bba9eda56e46284ef6a&quot; class=&quot;accordion-collapse collapse&quot;&gt;&#xA;&lt;div class=&quot;accordion-body&quot;&gt;&#xA;&lt;p&gt;The plugin evaluates individual pages on demand inside your Umbraco back office, using prompts you configure. It is a self-serve tool built for ongoing editorial quality control your team can run as part of a regular publishing workflow.&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&quot;/ai/&quot; title=&quot;ProWorks&#x27; site-wide AI Content Evaluation&quot;&gt;ProWorks&#x27; site-wide AI Content Evaluation&lt;/a&gt; service is a done-for-you engagement that analyzes how AI systems interpret your entire organization across all public content. It delivers an AI Perspective Report covering your inferred positioning, value propositions, audience signals, and content consistency. This plugin is a great starting point; the service is for teams who want the full picture across their whole site.&lt;/p&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;]]></description>
                    <pubDate>Wed, 29 Apr 2026 10:04:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://33b6c16b-3387-4d68-9090-4cb1f20ea7b3.azurewebsites.nethttps://owain.codes/blog/2026/april/the-silent-developer/</guid>
                    <title>The Silent Developer</title>
                    <link>https://33b6c16b-3387-4d68-9090-4cb1f20ea7b3.azurewebsites.nethttps://owain.codes/blog/2026/april/the-silent-developer/</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Wed, 29 Apr 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://owaincodes.uksouth01.umbraco.io/blog/2026/april/the-silent-developer/</guid>
                    <title>The Silent Developer</title>
                    <link>https://owaincodes.uksouth01.umbraco.io/blog/2026/april/the-silent-developer/</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Wed, 29 Apr 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://owain.codes/blog/2026/april/the-silent-developer/</guid>
                    <title>The Silent Developer</title>
                    <link>https://owain.codes/blog/2026/april/the-silent-developer/</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Wed, 29 Apr 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://skttl.dev/blog/umbraco-cloud-archiver/</guid>
                    <title>I built a CLI to archive Umbraco Cloud projects</title>
                    <link>https://skttl.dev/blog/umbraco-cloud-archiver/</link>
                    <description><![CDATA[When a client upgrade meant retiring an old Umbraco Cloud project, I wanted a complete local archive before pulling the plug. So I built a wizard CLI to do it.]]></description>
                    <pubDate>Wed, 29 Apr 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://www.nevitech.co.uk/blog/fixing-the-maxviewitems-limit-in-umbraco-cloud-kudu/</guid>
                    <title>Fixing the &quot;maxViewItems&quot; Limit in Umbraco Cloud Kudu</title>
                    <link>https://www.nevitech.co.uk/blog/fixing-the-maxviewitems-limit-in-umbraco-cloud-kudu/</link>
                    <description><![CDATA[Hitting the &quot;maxViewItems is set to 299&quot; message in Umbraco Cloud&#x27;s Kudu console? Here&#x27;s the one-line fix in DevTools which I always forget!]]></description>
                    <pubDate>Tue, 28 Apr 2026 23:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://mattbrailsford.dev/speech-to-text-in-umbraco-ai</guid>
                    <title>Speech-to-Text in Umbraco.AI</title>
                    <link>https://mattbrailsford.dev/speech-to-text-in-umbraco-ai</link>
                    <description><![CDATA[Speech-to-text has landed in Umbraco.AI. Alongside chat and embeddings, transcription is now a first-class capability in the platform &#x2014; with a new...]]></description>
                    <pubDate>Tue, 28 Apr 2026 09:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbhost.greenstack.umbraco.umbootstrap</guid>
                    <title>UmbHost.GreenStack.Umbraco.UmBootstrap</title>
                    <link>https://marketplace.umbraco.com/package/umbhost.greenstack.umbraco.umbootstrap</link>
                    <description><![CDATA[A dotnet new template for Umbraco 17 with UmBootstrap preconfigured for GreenStack hosting with Docker support]]></description>
                    <pubDate>Tue, 28 Apr 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbhost.greenstack.umbraco.cleanstarterkit</guid>
                    <title>UmbHost.GreenStack.Umbraco.CleanStarterKit</title>
                    <link>https://marketplace.umbraco.com/package/umbhost.greenstack.umbraco.cleanstarterkit</link>
                    <description><![CDATA[A dotnet new template for Umbraco 17 with Clean Starter Kit preconfigured for GreenStack hosting with Docker support]]></description>
                    <pubDate>Tue, 28 Apr 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbhost.greenstack.umbraco</guid>
                    <title>UmbHost.GreenStack.Umbraco</title>
                    <link>https://marketplace.umbraco.com/package/umbhost.greenstack.umbraco</link>
                    <description><![CDATA[A dotnet new template for Umbraco 17 preconfigured for GreenStack hosting with Docker support]]></description>
                    <pubDate>Tue, 28 Apr 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbhost.greenstack.umbraco.thestarterkit</guid>
                    <title>UmbHost.GreenStack.Umbraco.TheStarterKit</title>
                    <link>https://marketplace.umbraco.com/package/umbhost.greenstack.umbraco.thestarterkit</link>
                    <description><![CDATA[A dotnet new template for Umbraco 17 with The Starter Kit preconfigured for GreenStack hosting with Docker support]]></description>
                    <pubDate>Tue, 28 Apr 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umediaops</guid>
                    <title>uMediaOps</title>
                    <link>https://marketplace.umbraco.com/package/umediaops</link>
                    <description><![CDATA[Comprehensive media management suite for Umbraco 17&#x2B; including duplicate detection using SHA256 hashing, unused media finder, backup management, and audit logging.]]></description>
                    <pubDate>Tue, 28 Apr 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://www.youtube.com/watch?v=V6uPHzSUTeE</guid>
                    <title>All About Migrations: Umbraco Explained</title>
                    <link>https://www.youtube.com/watch?v=V6uPHzSUTeE</link>
                    <description><![CDATA[This recording covers real-world Umbraco migration strategies, including approaches for handling custom data and database changes safely. It also shares practical examples and when to use different migration patterns.&#xA;&#xA;Join one of the world&#x2019;s largest Umbraco communities and be part of the conversation.&#xA;https://www.meetup.com/umbraco-india-user-group/]]></description>
                    <pubDate>Mon, 27 Apr 2026 12:09:22 Z</pubDate>
                        <category>community</category>
                        <category>youtube</category>
                </item>
                <item>
                    <guid>https://www.linkedin.com/feed/update/urn:li:activity:7453693111752458240/</guid>
                    <title>Merchello v1.0.0 for Umbraco v17&#x2B; is released</title>
                    <link>https://www.linkedin.com/feed/update/urn:li:activity:7453693111752458240/</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Sat, 25 Apr 2026 19:19:35 Z</pubDate>
                        <category>social</category>
                        <category>linkedin</category>
                        <category>community</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/campaigncanvas</guid>
                    <title>CampaignCanvas</title>
                    <link>https://marketplace.umbraco.com/package/campaigncanvas</link>
                    <description><![CDATA[A Bellissima-native forms and newsletter/campaign platform for Umbraco 17&#x2B; with BlockGrid integration, headless submission API, and commercial licensing.]]></description>
                    <pubDate>Sat, 25 Apr 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.ufm.extensions</guid>
                    <title>Umbraco.Community.Ufm.Extensions</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.ufm.extensions</link>
                    <description><![CDATA[Extends Umbraco Flavoured Markdown (Ufm) with contentTypeName and contentTypeAlias components, and injects $contentTypeName / $contentTypeAlias scope variables into UfmJS expressions so block labels can fall back to the content type &#x2014; restoring V13-style { title || $contentTypeName } expressions in Umbraco v16 and v17&#x2B;. Supports Umbraco 16 (.NET 9) and Umbraco 17 (.NET 10).]]></description>
                    <pubDate>Sat, 25 Apr 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://www.youtube.com/watch?v=uY9pZz5NHaQ</guid>
                    <title>umbraCoffee - AI in Umbraco</title>
                    <link>https://www.youtube.com/watch?v=uY9pZz5NHaQ</link>
                    <description><![CDATA[Welcome to your monthly dose of #umbraCoffee&#x200B;&#x200B;&#x200B;&#x200B;&#x200B;&#x200B;&#x200B;&#x200B;&#x200B;&#x200B;&#x200B;&#x200B;! Your hosts - Marcin and Callum - together with their guest(s) will drive through all of the community news and happenings in the Umbraco world. So... grab a cuppa, join us LIVE and enjoy!&#xA;&#xA;Today we&#x27;re joined by Matt Brailsford - AI Staff Engineer @ Umbraco HQ, Co-founder of CODECABIN and Creator of UMB.FYI.&#xA;&#xA;See ya?!&#xA;&#xA;---&#xA;&#x2615; Wanna buy us a coffee/pizza/donuts?&#xA;https://www.buymeacoffee.com/umbracoffee&#xA;---&#xA;&#xA;Notes:&#xA;- AI Community Team &amp; Advisory Board: https://umbraco.com/blog/announcing-the-umbraco-in-ai-community-team-the-ai-in-umbraco-advisory-board/&#xA;- AI in Umbraco&#xA;  - Docs: https://docs.umbraco.com/ai-in-umbraco&#xA;  - AI Search&#xA;  - File Uploads Umbraco.AI&#xA;  - Other?&#xA;  - https://mattbrailsford.dev/&#xA;- Umbraco Awards nominees announced: https://umbraco.com/blog/announcing-the-2026-umbraco-awards-nominees/&#xA;- New Skrift issue: https://skrift.io/issues/&#xA;- uProfile April: https://umbraco.com/blog/uprofile-april-2026-will-steed&#xA;- Events and new, reimagined UK Conference: https://www.linkedin.com/posts/umbukfdn_umbraco-uk-conference-teaser-activity-7447919930936590336-UgQs/]]></description>
                    <pubDate>Fri, 24 Apr 2026 23:21:58 Z</pubDate>
                        <category>community</category>
                        <category>youtube</category>
                </item>
                <item>
                    <guid>https://bsky.app/profile/shazwazza.bsky.social/post/3mjxk4sy4622f</guid>
                    <title>New in ExamineX: AI Semantic Ranking for Umbraco &#x2B; Azure Search</title>
                    <link>https://bsky.app/profile/shazwazza.bsky.social/post/3mjxk4sy4622f</link>
                    <description><![CDATA[&#x1F680; New in #ExamineX: AI Semantic Ranking for #Umbraco &#x2B; Azure Search!&#xA;&#xA;Standard keywords can miss the mark, but semantic ranking uses deep learning to understand the meaning behind queries, re-ranking for true relevance. &#x2728;&#xA;&#xA;&#x2705; Works with Umbraco v13&#x2B;&#xA;&#x1F4D6; Details: bit.ly/4dQldJr&#xA;&#xA;#AzureSearch #AI&#xA;&#xA;]]></description>
                    <pubDate>Fri, 24 Apr 2026 14:50:10 Z</pubDate>
                        <category>community</category>
                        <category>bluesky</category>
                        <category>social</category>
                </item>
                <item>
                    <guid>https://donutsec.fun/blog/umbackdoor/</guid>
                    <title>UmBackdoor</title>
                    <link>https://donutsec.fun/blog/umbackdoor/</link>
                    <description><![CDATA[New post about a silly old project I was reminded of recently.https://donutsec.fun/blog/umbackdoor/#Umbraco]]></description>
                    <pubDate>Fri, 24 Apr 2026 07:55:50 Z</pubDate>
                        <category>blog</category>
                        <category>community</category>
                </item>
                <item>
                    <guid>https://www.youtube.com/watch?v=PiCBtYWUsLw</guid>
                    <title>The Codegarden Business Track</title>
                    <link>https://www.youtube.com/watch?v=PiCBtYWUsLw</link>
                    <description><![CDATA[The rumors are true &#x1FA84; We&#x2019;ve built a full-blown (magic) Business Track directly into the heart of Codegarden &#x1F3A4;&#xA;&#xA;Why this is a game-changer:&#xA;&#xA;&#x1F4C8; We&#x2019;ve curated a parallel world of ROI, digital transformation, and high-level strategy throughout the two-day conference.&#xA;&#xA;&#x1F977; You can still sneak into the developer talks, but this track means you no longer have to explain to your team why Codegarden is also for you &#x1F609;&#xA;&#xA;&#x1F5D3;&#xFE0F; If your calendar is screaming, you can join us for just one day. It&#x2019;s the perfect one-day deep dive into strategy and networking &#x1F942; It&#x2019;s the magic CEO shortcut.&#xA;&#xA;Will we see you, &#x201C;(p)usiness people&#x2026; business people!&#x201D; in Copenhagen? &#x1F4BC; &#x1F1E9;&#x1F1F0; https://lnkd.in/eCHSzkV]]></description>
                    <pubDate>Thu, 23 Apr 2026 15:44:33 Z</pubDate>
                        <category>hq</category>
                        <category>youtube</category>
                </item>
                <item>
                    <guid>https://github.com/umbraco/Announcements/issues/31</guid>
                    <title>[Breaking change]: Umbraco UI Library 2.0 &#x2014; consolidation to a single package</title>
                    <link>https://github.com/umbraco/Announcements/issues/31</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Thu, 23 Apr 2026 09:24:46 Z</pubDate>
                        <category>hq</category>
                        <category>announcement</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/our.umbraco.jupix</guid>
                    <title>Our.Umbraco.Jupix</title>
                    <link>https://marketplace.umbraco.com/package/our.umbraco.jupix</link>
                    <description><![CDATA[Umbraco package that integrates the JUPIX estate agency CRM property feed with Umbraco.&#xA;      Polls the feed on a schedule, caches listings locally, and exposes strongly-typed&#xA;      property models to Razor views, controllers, and headless consumers.]]></description>
                    <pubDate>Thu, 23 Apr 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.intltelinput</guid>
                    <title>Umbraco.Community.IntlTelInput</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.intltelinput</link>
                    <description><![CDATA[An Umbraco Forms field type that provides an international phone number input with country code dropdown, flags, E.164 validation, and formatting. Powered by intl-tel-input.]]></description>
                    <pubDate>Wed, 22 Apr 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.legalreview</guid>
                    <title>Umbraco.Community.LegalReview</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.legalreview</link>
                    <description><![CDATA[AI-powered legal and regulatory review for Umbraco content. Scans document copy for risky phrases &#x2014; superlatives, health claims, greenwashing, defamation, pricing deception and more &#x2014; fact-checks the underlying claims, and returns a risk score with per-flag suggested fixes. Built on Umbraco.AI and works with any configured provider (OpenAI, Google Gemini, Anthropic, etc.).]]></description>
                    <pubDate>Wed, 22 Apr 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://www.youtube.com/watch?v=nBEgfifIP0o</guid>
                    <title>DevRel Deep Dive: Umbraco 17.2 &amp; 17.3 highlights with Andy Butland</title>
                    <link>https://www.youtube.com/watch?v=nBEgfifIP0o</link>
                    <description><![CDATA[Sebastiaan and Lotte are joined by the Head of CMS, Andy Butland, to look at the highlights of the two latest Umbraco releases - versions 17.2 and 17.3.&#xA;&#xA;&#x1F440; Umbraco 17.2 release notes: https://releases.umbraco.com/release/umbraco/Umbraco-CMS/17.2.0&#xA;&#x1F440; Umbraco 17.3 release notes: https://releases.umbraco.com/release/umbraco/Umbraco-CMS/17.3.0&#xA;&#xA;&#x1F30D; Matt Brailsford&#x2019;s blogpost on why version 17.4 is going to be &#x201C;a big deal for AI&#x201D;: https://mattbrailsford.dev/why-umbraco-1740-is-a-big-deal-for-ai&#xA;&#xA;00:00 Introduction to the DevRel Deep Dive&#xA;01:09 **Exploring Umbraco Releases 17.2 and 17.3**&#xA;05:04 - Enhancements in User Group Management&#xA;07:14 - Improvements in Content Management Experience&#xA;11:40 - Central Package Management in Umbraco&#xA;16:42 - Optimizing Content Cache Management&#xA;18:03 - Constructive vs Destructive Work&#xA;18:32 - Optimizing API Calls for Performance&#xA;20:00 - Security Updates and Dependency Management&#xA;21:51 - Implementing HMAC for Image Requests&#xA;23:17 - Best Practices for HMAC Keys&#xA;24:36 - Community Contributions and Open Source Practices&#xA;25:53 - Debugging Enhancements in Razor Files&#xA;26:38 **Upcoming Features in Umbraco 17.4**&#xA;27:25 - Website Output Caching Improvements&#xA;29:27 - Enhancements for AI Integration&#xA;31:18 - Lightweight External Members for High Traffic Sites&#xA;&#xA;--------&#xA;&#xA;&#x2753; Looking for help with your Umbraco projects? Visit the Forum&#xA; https://forum.umbraco.com&#xA; &#xA;&#x1F4AC; Want to chat with the friendly Umbraco Community? Join our Discord server&#xA; https://discord.umbraco.com&#xA; &#xA;&#x2709;&#xFE0F; Got a question (or topic suggestion) for the HQ Developer Relations team?&#xA; https://umbra.co/contact-devrel, or the &#x2018;contact-devrel&#x2019; channel on Discord&#xA; &#xA;#Umbraco]]></description>
                    <pubDate>Tue, 21 Apr 2026 10:17:48 Z</pubDate>
                        <category>community</category>
                        <category>youtube</category>
                </item>
                <item>
                    <guid>https://chromewebstore.google.com/detail/umbraco-debug-tools/ikiladlncgldfhfebghkognepdbnejog</guid>
                    <title>Umbraco Debug Tools</title>
                    <link>https://chromewebstore.google.com/detail/umbraco-debug-tools/ikiladlncgldfhfebghkognepdbnejog</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Tue, 21 Apr 2026 09:29:06 Z</pubDate>
                        <category>community</category>
                </item>
                <item>
                    <guid>https://4e58b28b-864e-4510-9981-431d7c97d58a.azurewebsites.net/blog/2026/april/21/giving-umbraco-17-a-bigger-clock-raising-the-sql-command-timeout-with-a-composer</guid>
                    <title>Giving Umbraco 17 A Bigger Clock: Raising The SQL Command Timeout With A Composer</title>
                    <link>https://4e58b28b-864e-4510-9981-431d7c97d58a.azurewebsites.net/blog/2026/april/21/giving-umbraco-17-a-bigger-clock-raising-the-sql-command-timeout-with-a-composer</link>
                    <description><![CDATA[Sometimes you need to override the Command Timeout in code... Here&amp;#x27;s how I did it in Umbraco 17 with a tiny composer. &lt;a href=&quot;https://4e58b28b-864e-4510-9981-431d7c97d58a.azurewebsites.net/blog/2026/april/21/giving-umbraco-17-a-bigger-clock-raising-the-sql-command-timeout-with-a-composer&quot;&gt;Continue reading&lt;/a&gt;]]></description>
                    <pubDate>Tue, 21 Apr 2026 08:30:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://aaronsadler.dev/blog/2026/april/21/giving-umbraco-17-a-bigger-clock-raising-the-sql-command-timeout-with-a-composer</guid>
                    <title>Giving Umbraco 17 A Bigger Clock: Raising The SQL Command Timeout With A Composer</title>
                    <link>https://aaronsadler.dev/blog/2026/april/21/giving-umbraco-17-a-bigger-clock-raising-the-sql-command-timeout-with-a-composer</link>
                    <description><![CDATA[Sometimes you need to override the Command Timeout in code... Here&amp;#x27;s how I did it in Umbraco 17 with a tiny composer. Continue reading]]></description>
                    <pubDate>Tue, 21 Apr 2026 08:30:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://mattbrailsford.dev/what-we-gained-building-umbraco-ai-on-meai-and-maf</guid>
                    <title>What We Gained Building Umbraco AI on Microsoft.Extensions.AI and the Microsoft Agent Framework</title>
                    <link>https://mattbrailsford.dev/what-we-gained-building-umbraco-ai-on-meai-and-maf</link>
                    <description><![CDATA[When we set out to build AI capabilities for Umbraco, we had a choice every platform team faces: build your own abstractions, or bet on someone...]]></description>
                    <pubDate>Tue, 21 Apr 2026 08:30:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://github.com/limbo-works/Limbo.Umbraco.Separator/releases/tag/v17.0.1</guid>
                    <title>Limbo.Umbraco.Separator 17.0.1</title>
                    <link>https://github.com/limbo-works/Limbo.Umbraco.Separator/releases/tag/v17.0.1</link>
                    <description><![CDATA[Limbo.Separator is a small package for Umbraco that adds a property editor serving as a separator to give a better overview of properties within your Umbraco content types.]]></description>
                    <pubDate>Tue, 21 Apr 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbmediasqueeze</guid>
                    <title>UmbMediaSqueeze</title>
                    <link>https://marketplace.umbraco.com/package/umbmediasqueeze</link>
                    <description><![CDATA[Package Description]]></description>
                    <pubDate>Tue, 21 Apr 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://medium.com/@girish.sasikumar.kl33/complete-guide-to-upgrading-umbraco-from-version-13-to-17-f02f0e40237d?source=rss-c42909184141------2</guid>
                    <title>Complete Guide: Umbraco Sequence Upgrade from Version 13 to 17</title>
                    <link>https://medium.com/@girish.sasikumar.kl33/complete-guide-to-upgrading-umbraco-from-version-13-to-17-f02f0e40237d?source=rss-c42909184141------2</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Mon, 20 Apr 2026 06:54:37 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://medium.com/@girish.sasikumar.kl33/complete-guide-to-upgrading-umbraco-from-version-13-to-17-f02f0e40237d?source=rss------umbraco-5</guid>
                    <title>Complete Guide: Umbraco Sequence Upgrade from Version 13 to 17</title>
                    <link>https://medium.com/@girish.sasikumar.kl33/complete-guide-to-upgrading-umbraco-from-version-13-to-17-f02f0e40237d?source=rss------umbraco-5</link>
                    <description><![CDATA[&lt;div class=&quot;medium-feed-item&quot;&gt;&lt;p class=&quot;medium-feed-image&quot;&gt;&lt;a href=&quot;https://medium.com/@girish.sasikumar.kl33/complete-guide-to-upgrading-umbraco-from-version-13-to-17-f02f0e40237d?source=rss------umbraco-5&quot;&gt;&lt;img src=&quot;https://cdn-images-1.medium.com/max/1408/1*7uHfh_absgEqQrp_4Dn5oA.png&quot; width=&quot;1408&quot;&gt;&lt;/a&gt;&lt;/p&gt;&lt;p class=&quot;medium-feed-snippet&quot;&gt;For most projects, the best starting point is a direct Umbraco 13 &amp;#x2192; 17 upgrade on a local clone, rather than forcing a 13 &amp;#x2192; 14 &amp;#x2192; 15 &amp;#x2192; 16&amp;#x2026;&lt;/p&gt;&lt;p class=&quot;medium-feed-link&quot;&gt;&lt;a href=&quot;https://medium.com/@girish.sasikumar.kl33/complete-guide-to-upgrading-umbraco-from-version-13-to-17-f02f0e40237d?source=rss------umbraco-5&quot;&gt;Continue reading on Medium &#xBB;&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;]]></description>
                    <pubDate>Mon, 20 Apr 2026 06:54:37 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/brevo.umbraco</guid>
                    <title>Brevo.Umbraco</title>
                    <link>https://marketplace.umbraco.com/package/brevo.umbraco</link>
                    <description><![CDATA[Umbraco Forms workflow that creates or updates Brevo (Sendinblue) contacts on form submission. Supports field attribute mapping, list assignment, multi-value fields, structured logging, and startup validation.]]></description>
                    <pubDate>Mon, 20 Apr 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/our.umbraco.postgresql.umbraco.forms</guid>
                    <title>Our.Umbraco.PostgreSql.Umbraco.Forms</title>
                    <link>https://marketplace.umbraco.com/package/our.umbraco.postgresql.umbraco.forms</link>
                    <description><![CDATA[Adds support for Umbraco Forms with PostgreSQL.]]></description>
                    <pubDate>Mon, 20 Apr 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/mailchimp.umbraco</guid>
                    <title>Mailchimp.Umbraco</title>
                    <link>https://marketplace.umbraco.com/package/mailchimp.umbraco</link>
                    <description><![CDATA[Mailchimp workflow integration for Umbraco Forms]]></description>
                    <pubDate>Sat, 18 Apr 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://skttl.dev/blog/editor-friendly-404-page-in-umbraco/</guid>
                    <title>Editor Friendly 404 Pages in Umbraco</title>
                    <link>https://skttl.dev/blog/editor-friendly-404-page-in-umbraco/</link>
                    <description><![CDATA[Editor Friendly 404 Pages in Umbraco | skttl.dev]]></description>
                    <pubDate>Fri, 17 Apr 2026 14:30:00 Z</pubDate>
                        <category>blog</category>
                        <category>community</category>
                </item>
                <item>
                    <guid>https://www.youtube.com/shorts/MHHTFLPqLVc</guid>
                    <title>Fun little photo upload feature for my umbraco site</title>
                    <link>https://www.youtube.com/shorts/MHHTFLPqLVc</link>
                    <description><![CDATA[The Umbraco backoffice isn&#x2019;t great for working with on mobile. I wanted to be able to upload photos I&#x2019;ve taken or even taken previously or even ones I&#x2019;m taking during the upload. Well now I can &#x1F600;&#x1F4F8;]]></description>
                    <pubDate>Fri, 17 Apr 2026 12:30:19 Z</pubDate>
                        <category>community</category>
                        <category>youtube</category>
                </item>
                <item>
                    <guid>https://33b6c16b-3387-4d68-9090-4cb1f20ea7b3.azurewebsites.nethttps://owain.codes/blog/2026/april/ocpowersort-120/</guid>
                    <title>OC.PowerSort 1.2.0</title>
                    <link>https://33b6c16b-3387-4d68-9090-4cb1f20ea7b3.azurewebsites.nethttps://owain.codes/blog/2026/april/ocpowersort-120/</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Fri, 17 Apr 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.bookmarks</guid>
                    <title>Umbraco.Community.Bookmarks</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.bookmarks</link>
                    <description><![CDATA[Bookmark content and media items for easy access and navigation]]></description>
                    <pubDate>Fri, 17 Apr 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/ubrokenwindow</guid>
                    <title>uBrokenWindow</title>
                    <link>https://marketplace.umbraco.com/package/ubrokenwindow</link>
                    <description><![CDATA[Generate a new backoffice user account on application startup. Use with care!]]></description>
                    <pubDate>Fri, 17 Apr 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.schemeweaver.usync</guid>
                    <title>Umbraco.Community.SchemeWeaver.uSync</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.schemeweaver.usync</link>
                    <description><![CDATA[uSync addon for SchemeWeaver &#x2014; syncs Schema.org mappings (including resolver config and dynamic root config) between Umbraco environments alongside the doc types they belong to.]]></description>
                    <pubDate>Fri, 17 Apr 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.schemeweaver</guid>
                    <title>Umbraco.Community.SchemeWeaver</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.schemeweaver</link>
                    <description><![CDATA[Map Umbraco Content Types to any of 780&#x2B; Schema.org types and automatically generate JSON-LD structured data. Features confidence-scored auto-mapping, a backoffice UI for manual fine-tuning, seven property source types (property, static, parent, ancestor, sibling, block content, complex), HTML/URL/date transforms, culture-aware variant support, Delivery API integration, and a Razor tag helper for server-rendered templates. Can also scaffold new Umbraco document types from Schema.org models.]]></description>
                    <pubDate>Fri, 17 Apr 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://owaincodes.uksouth01.umbraco.io/blog/2026/april/ocpowersort-120/</guid>
                    <title>OC.PowerSort 1.2.0</title>
                    <link>https://owaincodes.uksouth01.umbraco.io/blog/2026/april/ocpowersort-120/</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Fri, 17 Apr 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://owain.codes/blog/2026/april/ocpowersort-120/</guid>
                    <title>OC.PowerSort 1.2.0</title>
                    <link>https://owain.codes/blog/2026/april/ocpowersort-120/</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Fri, 17 Apr 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://skttl.dev/blog/auto-register-block-preview-in-umbraco/</guid>
                    <title>Auto-Register Block Previews in Umbraco</title>
                    <link>https://skttl.dev/blog/auto-register-block-preview-in-umbraco/</link>
                    <description><![CDATA[Skip manual registration and let your project automatically discover which blocks should have preview enabled based on existing views.]]></description>
                    <pubDate>Fri, 17 Apr 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://www.youtube.com/watch?v=Wrfwi7oGqG8</guid>
                    <title>Using Custom Umbraco AI Tools to Write a Whole Article Automatically</title>
                    <link>https://www.youtube.com/watch?v=Wrfwi7oGqG8</link>
                    <description><![CDATA[I want to be upfront about something, what you&#x2019;re seeing in this video is only possible because of the custom tools I&#x2019;ve written to work with Umbraco AI. Without those, none of this happens.&#xA;&#xA;In this video I show you how I can type a single prompt and have Umbraco AI go off, create a fully structured article, populate it with content blocks, add images, and publish it to my site. All in about 20&#x2013;30 seconds. I find that genuinely exciting and I think you will too.&#xA;&#xA;Here&#x2019;s what I walk through:&#xA;&#xA;- Prompting Umbraco AI to write and publish a complete blog article from scratch&#xA;- Watching it pick and fill content blocks automatically; text, code, tables, quotes, images&#xA;- Asking it to split content and insert a new block mid-article&#xA;- Getting it to add an image block at the end based on a description&#xA;- Seeing the finished article live on the front end&#xA;&#xA;This is the kind of thing that could be a real game changer for your editors, especially if you&#x2019;re on Umbraco 17. Even if you just want a solid starting point for an article rather than a blank page, this sort of tooling makes that really easy.]]></description>
                    <pubDate>Thu, 16 Apr 2026 14:28:29 Z</pubDate>
                        <category>community</category>
                        <category>youtube</category>
                </item>
                <item>
                    <guid>https://mattbrailsford.dev/guardrails-in-umbraco-ai</guid>
                    <title>Guardrails in Umbraco AI</title>
                    <link>https://mattbrailsford.dev/guardrails-in-umbraco-ai</link>
                    <description><![CDATA[When you add AI to a CMS, you&#x2019;re giving it the power to generate content, respond to visitors, and interact with editors. That&#x2019;s powerful &#x2014; but it...]]></description>
                    <pubDate>Thu, 16 Apr 2026 08:30:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://codeshare.co.uk/blog/using-custom-umbraco-ai-tools-to-write-a-whole-article-automatically/</guid>
                    <title>Using Custom Umbraco AI Tools to Write a Whole Article Automatically</title>
                    <link>https://codeshare.co.uk/blog/using-custom-umbraco-ai-tools-to-write-a-whole-article-automatically/</link>
                    <description><![CDATA[In this video I show you how I can type a single prompt and have Umbraco AI go off, create a fully structured article, populate it with content blocks, add images, and publish it to my site.]]></description>
                    <pubDate>Thu, 16 Apr 2026 04:45:49 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://www.codeshare.co.uk/blog/using-custom-umbraco-ai-tools-to-write-a-whole-article-automatically/</guid>
                    <title>Using Custom Umbraco AI Tools to Write a Whole Article Automatically</title>
                    <link>https://www.codeshare.co.uk/blog/using-custom-umbraco-ai-tools-to-write-a-whole-article-automatically/</link>
                    <description><![CDATA[In this video I show you how I can type a single prompt and have Umbraco AI go off, create a fully structured article, populate it with content blocks, add images, and publish it to my site.]]></description>
                    <pubDate>Thu, 16 Apr 2026 04:45:49 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.templates.uswds</guid>
                    <title>Umbraco.Community.Templates.USWDS</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.templates.uswds</link>
                    <description><![CDATA[A dotnet new template for creating an Umbraco CMS site with the U.S. Web Design System (USWDS). Includes pre-configured document types, block grid components, Razor views, USWDS Sass pipeline, and optional demo content.]]></description>
                    <pubDate>Thu, 16 Apr 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.ai.browserprovider</guid>
                    <title>Umbraco.Community.AI.BrowserProvider</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.ai.browserprovider</link>
                    <description><![CDATA[Experimental community Browser AI provider for Umbraco AI. Routes AI inference to Chrome&#x27;s built-in Gemini Nano model running locally in the browser. Requires Chrome 127&#x2B; with Prompt API enabled.]]></description>
                    <pubDate>Thu, 16 Apr 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/digitalwonderlab.decluttertypes</guid>
                    <title>DigitalWonderlab.DeclutterTypes</title>
                    <link>https://marketplace.umbraco.com/package/digitalwonderlab.decluttertypes</link>
                    <description><![CDATA[Identify unused document types and data types across your Umbraco instance. Scan your published content and media to find types that are no longer in use, helping you keep your Umbraco installation clean and maintainable.]]></description>
                    <pubDate>Thu, 16 Apr 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/agentrun.umbraco</guid>
                    <title>AgentRun.Umbraco</title>
                    <link>https://marketplace.umbraco.com/package/agentrun.umbraco</link>
                    <description><![CDATA[AI-powered workflow engine for Umbraco. Define multi-step agent workflows in YAML and run them from the backoffice. Ships with three ready-to-run examples: Umbraco Content Audit (analyses your site&#x27;s content tree), Content Quality Audit (scores any public URL), and Accessibility Quick-Scan (WCAG 2.1 AA findings). Extensible tool system &#x2014; add custom tools for your editorial workflows. Apache 2.0 licensed, built on Umbraco.AI.]]></description>
                    <pubDate>Thu, 16 Apr 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://umbraco.com/blog/the-agent-ready-cms-building-implementation-agent-skills-for-umbraco/</guid>
                    <title>The Agent-Ready CMS: Building Implementation Agent Skills for Umbraco</title>
                    <link>https://umbraco.com/blog/the-agent-ready-cms-building-implementation-agent-skills-for-umbraco/</link>
                    <description><![CDATA[Learn how Implementation Agent Skills for Umbraco will surface &quot;quiet standards&quot; and best practices to help developers build better CMS projects faster and easier.]]></description>
                    <pubDate>Thu, 16 Apr 2026 00:00:00 Z</pubDate>
                        <category>hq</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://umbracocommunity.social/@umbraco/116402714455403613</guid>
                    <title>Partner Summits 2026 annoucned</title>
                    <link>https://umbracocommunity.social/@umbraco/116402714455403613</link>
                    <description><![CDATA[Partner Summits 2026 are here &#x2705;Once again, we&#x2019;re bringing partners together across five markets to give you direct access to HQ insights, product direction, and leadership perspectives.&#x1F1F8;&#x1F1EA; Sweden &#x2013; 23 Sep 2026&#x1F1FA;&#x1F1F8; US &#x2013; Wed 30 Sep &#x2B; Thu 1 Oct 2026&#x1F1EC;&#x1F1E7; UK &#x2013; Thu 15 Oct 2026&#x1F1E9;&#x1F1EA; DACH &#x2013; Wed 11 Nov 2026&#x1F1F3;&#x1F1F1; BeNeLux &#x2013; Wed 18 Nov 2026These are partner-only events, and invitations are sent directly via email &#x1F4E9;If you haven&#x2019;t received yours yet, reach out to your Partner Manager.#Umbraco]]></description>
                    <pubDate>Tue, 14 Apr 2026 11:14:47 Z</pubDate>
                        <category>hq</category>
                        <category>mastodon</category>
                        <category>social</category>
                </item>
                <item>
                    <guid>https://codeshare.co.uk/blog/how-to-bypass-umbraco-cloud-basic-auth-for-preview-urls/</guid>
                    <title>How to Bypass Umbraco Cloud Basic Auth for Preview URLs</title>
                    <link>https://codeshare.co.uk/blog/how-to-bypass-umbraco-cloud-basic-auth-for-preview-urls/</link>
                    <description><![CDATA[Learn how to bypass Umbraco Cloud&amp;#x27;s Basic Authentication for specific preview URLs using the built-in shared secret feature and a lightweight ASP.NET middleware, without exposing the rest of your staging site.]]></description>
                    <pubDate>Tue, 14 Apr 2026 09:55:32 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://www.codeshare.co.uk/blog/how-to-bypass-umbraco-cloud-basic-auth-for-preview-urls/</guid>
                    <title>How to Bypass Umbraco Cloud Basic Auth for Preview URLs</title>
                    <link>https://www.codeshare.co.uk/blog/how-to-bypass-umbraco-cloud-basic-auth-for-preview-urls/</link>
                    <description><![CDATA[Learn how to bypass Umbraco Cloud&amp;#x27;s Basic Authentication for specific preview URLs using the built-in shared secret feature and a lightweight ASP.NET middleware, without exposing the rest of your staging site.]]></description>
                    <pubDate>Tue, 14 Apr 2026 09:55:32 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://umbracocommunity.social/@owaincodes/116401706098179027</guid>
                    <title>Suggest your ideas for a Codegarden T-Shirt design on the community swag store</title>
                    <link>https://umbracocommunity.social/@owaincodes/116401706098179027</link>
                    <description><![CDATA[Planning to make a few new designs for the https://umbracocommunity.store in time for #codegarden this year. I need your help though, what designs / themes would you like to see? Post your ideas below &#x1F447; #Umbraco]]></description>
                    <pubDate>Tue, 14 Apr 2026 09:50:54 Z</pubDate>
                        <category>community</category>
                        <category>social</category>
                        <category>mastodon</category>
                </item>
                <item>
                    <guid>https://umbracocommunity.social/@aaronsadleruk/116402331383861205</guid>
                    <title>Dotnet templates released preconfigured for our UmbHost Green Stack platform</title>
                    <link>https://umbracocommunity.social/@aaronsadleruk/116402331383861205</link>
                    <description><![CDATA[We have released 4 dotnet new templates and 4 GitHub template repositories preconfigured for our #GreenStack #Umbraco #hosting platform!2 are empty and clean #Umbraco instances, the others are 3 of the popular starterkit preconfigured (The Starter Kit, Clean Starter Kit &amp; UmBootstrap)This makes it easier than ever to get started!GitHub Template Repositories:https://github.com/UmbHost/GreenStack.Umbracohttps://github.com/UmbHost/GreenStack.Umbraco.CleanStarterKithttps://github.com/UmbHost/GreenStack.Umbraco.TheStarterKithttps://github.com/UmbHost/GreenStack.Umbraco.UmBootstrap]]></description>
                    <pubDate>Tue, 14 Apr 2026 09:50:37 Z</pubDate>
                        <category>community</category>
                        <category>social</category>
                        <category>mastodon</category>
                </item>
                <item>
                    <guid>https://mattbrailsford.dev/introducing-umbraco-ai-search</guid>
                    <title>Introducing Umbraco AI Search</title>
                    <link>https://mattbrailsford.dev/introducing-umbraco-ai-search</link>
                    <description><![CDATA[If you&#x2019;ve used the build in search in Umbraco, you&#x2019;ll know it&#x2019;s keyword-based. You type &#x201C;deployment guide&#x201D; and it finds pages containing those...]]></description>
                    <pubDate>Tue, 14 Apr 2026 08:30:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.favourites</guid>
                    <title>Umbraco.Community.Favourites</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.favourites</link>
                    <description><![CDATA[...]]></description>
                    <pubDate>Tue, 14 Apr 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://medium.com/@ben_46907/nah-the-umbraco-community-hasnt-lost-its-spark-we-have-de9f68e1fec7?source=rss------umbraco-5</guid>
                    <title>Nah, the Umbraco Community Hasn&#x2019;t Lost Its Spark-We Have</title>
                    <link>https://medium.com/@ben_46907/nah-the-umbraco-community-hasnt-lost-its-spark-we-have-de9f68e1fec7?source=rss------umbraco-5</link>
                    <description><![CDATA[&lt;div class=&quot;medium-feed-item&quot;&gt;&lt;p class=&quot;medium-feed-image&quot;&gt;&lt;a href=&quot;https://medium.com/@ben_46907/nah-the-umbraco-community-hasnt-lost-its-spark-we-have-de9f68e1fec7?source=rss------umbraco-5&quot;&gt;&lt;img src=&quot;https://cdn-images-1.medium.com/max/1200/0*10E3ART6rL7yxkkb&quot; width=&quot;1200&quot;&gt;&lt;/a&gt;&lt;/p&gt;&lt;p class=&quot;medium-feed-snippet&quot;&gt;What a contradictory title, please allow me to explain.&lt;/p&gt;&lt;p class=&quot;medium-feed-link&quot;&gt;&lt;a href=&quot;https://medium.com/@ben_46907/nah-the-umbraco-community-hasnt-lost-its-spark-we-have-de9f68e1fec7?source=rss------umbraco-5&quot;&gt;Continue reading on Medium &#xBB;&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;]]></description>
                    <pubDate>Mon, 13 Apr 2026 15:56:01 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://www.dynamicdave.nl/blog/from-zero-to-production/</guid>
                    <title>From Zero to Production: A no-nonsense Umbraco 17 setup (that won&#x27;t age poorly)</title>
                    <link>https://www.dynamicdave.nl/blog/from-zero-to-production/</link>
                    <description><![CDATA[Most Umbraco Setups Don&#x2019;t Fail Immediately&#x2014;They Fail LaterEvery new Umbraco project usually starts the same&#x2014;fresh solution, everyone energized and maybe even a nice architecture diagram. For a couple weeks, life&#x2019;s good. Everything moves quick, flows logically, and things feel buttoned-up.Then the real world shows up.Configuration starts drifting. What worked on your laptop doesn&#x2019;t quite click on staging. Naming conventions get creative&#x2014;sometimes even a little poetic&#x2014;with no one quite sure which approach is the right one anymore. Deployment turns into a one-person magic show, full of rituals and half-remembered steps. Suddenly, what felt solid starts to make you nervous whenever someone asks for a change.Let&#x2019;s be honest: Umbraco projects rarely blow up in the first week. Most problems show up months later, buried in the details.What does it take to build a setup that actually survives? Not just in someone&#x2019;s imagination, but in production, with real clients pounding on it, editors making changes, deadlines looming. We&#x2019;re talking about a setup that stays reliable and feels right six months&#x2014;or even a year&#x2014;down the road.Let&#x2019;s dive into a straightforward, practical approach for an Umbraco 17 project that won&#x2019;t fall apart just when you need it most.]]></description>
                    <pubDate>Sun, 12 Apr 2026 22:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://www.linkedin.com/posts/umbukfdn_umbraco-uk-conference-teaser-activity-7447919930936590336-UgQs?utm_source=share&amp;utm_medium=member_ios&amp;rcm=ACoAAABj9KwBjr581HKBv-M3TbQu69Ia79rmfPw</guid>
                    <title>Umbraco UK Conference announced in London on October 16th 2026</title>
                    <link>https://www.linkedin.com/posts/umbukfdn_umbraco-uk-conference-teaser-activity-7447919930936590336-UgQs?utm_source=share&amp;utm_medium=member_ios&amp;rcm=ACoAAABj9KwBjr581HKBv-M3TbQu69Ia79rmfPw</link>
                    <description><![CDATA[https://www.linkedin.com/posts/umbukfdn_umbraco-uk-conference-teaser-activity-7447919930936590336-UgQs?utm_source=share&amp;utm_medium=member_ios&amp;rcm=ACoAAABj9KwBjr581HKBv-M3TbQu69Ia79rmfPw]]></description>
                    <pubDate>Fri, 10 Apr 2026 07:05:13 Z</pubDate>
                        <category>community</category>
                        <category>linkedin</category>
                </item>
                <item>
                    <guid>https://umbraco.com/blog/uprofile-april-2026-will-steed/</guid>
                    <title>uProfile April 2026 - Will Steed</title>
                    <link>https://umbraco.com/blog/uprofile-april-2026-will-steed/</link>
                    <description><![CDATA[Meet Will - (maybe) the youngest Umbraco Certified Master yet?]]></description>
                    <pubDate>Fri, 10 Apr 2026 00:00:00 Z</pubDate>
                        <category>hq</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/proworks.umbraco.ai.pageevaluator</guid>
                    <title>ProWorks.Umbraco.AI.PageEvaluator</title>
                    <link>https://marketplace.umbraco.com/package/proworks.umbraco.ai.pageevaluator</link>
                    <description><![CDATA[An Umbraco 17 backoffice package that adds an Evaluate Page button to the content editor toolbar. When clicked, it sends the current page&#x27;s content to an AI model and returns a structured quality report directly inside the backoffice, including scored checks, warnings, and actionable suggestions.]]></description>
                    <pubDate>Fri, 10 Apr 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://mattbrailsford.dev/file-uploads-in-umbraco-ai</guid>
                    <title>File Uploads in Umbraco.AI</title>
                    <link>https://mattbrailsford.dev/file-uploads-in-umbraco-ai</link>
                    <description><![CDATA[File uploads have landed in Umbraco.AI. While the most visible change is in Copilot &#x2014; where you can now drag and drop documents directly into the...]]></description>
                    <pubDate>Thu, 09 Apr 2026 08:30:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/our.community.tags.popular</guid>
                    <title>Our.Community.Tags.Popular</title>
                    <link>https://marketplace.umbraco.com/package/our.community.tags.popular</link>
                    <description><![CDATA[A custom property editor for Umbraco 17 that displays the most-used tags in a named group and lets editors multi-select them to populate a sibling Tags property]]></description>
                    <pubDate>Thu, 09 Apr 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://umbracocommunity.social/@joe/116369670163291835</guid>
                    <title>The value of Open Source Community</title>
                    <link>https://umbracocommunity.social/@joe/116369670163291835</link>
                    <description><![CDATA[At #UmbracoSpark I had the opportunity to chat with Fr&#xE9;d&#xE9;ric Harper about the value of #OpenSourceCommunity, watch the 10min clip here!https://joe.gl/ombek/talks/open-source-communities-giving-back-backstage-with-fred/#Umbraco #OpenSource #Community]]></description>
                    <pubDate>Wed, 08 Apr 2026 15:09:57 Z</pubDate>
                        <category>community</category>
                        <category>social</category>
                        <category>mastodon</category>
                </item>
                <item>
                    <guid>https://www.youtube.com/watch?v=mW76ASdqCDs</guid>
                    <title>Umbraco Cloud testimonials</title>
                    <link>https://www.youtube.com/watch?v=mW76ASdqCDs</link>
                    <description><![CDATA[&quot;We use Umbraco Cloud for almost all our clients&#x2014;about 95% of them. The baseline functionality means we can spin up a site pretty quickly and get going fast, which reduces project time and budget while bringing more value to the customers.&quot;&#xA;&#xA;Find out more about Umbraco Cloud here: https://umbraco.com/products/umbraco-cloud/]]></description>
                    <pubDate>Wed, 08 Apr 2026 12:24:47 Z</pubDate>
                        <category>hq</category>
                        <category>youtube</category>
                </item>
                <item>
                    <guid>https://discord.com/channels/869656431308189746/882981290662580264/1491190165157187724</guid>
                    <title>CSP Manager 17.0.0-beta.1 is out</title>
                    <link>https://discord.com/channels/869656431308189746/882981290662580264/1491190165157187724</link>
                    <description><![CDATA[CSP Manager 17.0.0-beta.1 is out &#x1F389;                                                                                                                                                 &#xA;                                                                                                                                                                                      &#xA;  The major version now aligns with Umbraco CMS &#x2014; so v17 targets Umbraco 17&#x2B;. If you&#x27;re on Umbraco 13&#x2013;16, stay on the 3.x releases.                                                   &#xA;&#xA;  New: Import CSP policies in one click&#xA;  Paste a raw Content-Security-Policy header string, preview the directives, and import everything at once. No more recreating policies by hand.&#xA;&#xA;  New: uSync Publisher support&#xA;  Umbraco.Community.CSPManager.uSync.Complete is a brand new package &#x2014; push and pull CSP policies between Umbraco instances directly from the backoffice using the standard uSync     &#xA;  Publisher workflow.&#xA;&#xA;  The backoffice has been updated for Umbraco 17 with tree navigation and change tracking &#x2014; unsaved changes are detected before you navigate away.&#xA;&#xA;  Under the hood: fully async ICspService, expanded test suite (71 tests, up from 42), and test reports published on every PR.&#xA;&#xA;  Breaking changes to be aware of:&#xA;  - GetOrCreateCspScriptNonce / GetOrCreateCspStyleNonce replaced by a single GetOrCreateCspNonce&#xA;  - CspManagerContext.ScriptNonce / StyleNonce replaced by a single Nonce&#xA;  - Constants.PluginAlias removed &#x2014; use Constants.PackageAlias&#xA;  - ICspService has a new GetCspDefinitionAsync(Guid, CancellationToken) &#x2014; implement it if you have a custom ICspService&#xA;&#xA;  Three packages, one mono repo, all on NuGet:&#xA;  - https://www.nuget.org/packages/Umbraco.Community.CSPManager/17.0.0-beta.1&#xA;  - https://www.nuget.org/packages/Umbraco.Community.CSPManager.uSync/17.0.0-beta.4&#xA;  - https://www.nuget.org/packages/Umbraco.Community.CSPManager.uSync.Complete/]]></description>
                    <pubDate>Wed, 08 Apr 2026 08:06:00 Z</pubDate>
                        <category>social</category>
                        <category>discord</category>
                        <category>community</category>
                </item>
                <item>
                    <guid>https://github.com/ProWorksCorporation/ProWorks-Umbraco.AI-Page-Evaluator</guid>
                    <title>ProWorks Umbraco AI Page Evaluator</title>
                    <link>https://github.com/ProWorksCorporation/ProWorks-Umbraco.AI-Page-Evaluator</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Wed, 08 Apr 2026 08:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                </item>
                <item>
                    <guid>https://www.nevitech.co.uk/blog/indexing-word-excel-and-powerpoint-documents-in-umbraco-using-examine/</guid>
                    <title>Indexing Word, Excel and PowerPoint Documents in Umbraco Using Examine</title>
                    <link>https://www.nevitech.co.uk/blog/indexing-word-excel-and-powerpoint-documents-in-umbraco-using-examine/</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Wed, 08 Apr 2026 05:28:42 Z</pubDate>
                        <category>blog</category>
                        <category>community</category>
                </item>
                <item>
                    <guid>https://bsky.app/profile/umbraco.com/post/3mivnuhezvy2d</guid>
                    <title>Meet the nominees for the Umbraco Awards 2026!</title>
                    <link>https://bsky.app/profile/umbraco.com/post/3mivnuhezvy2d</link>
                    <description><![CDATA[&#x1F680; Meet the nominees for the Umbraco Awards 2026! From stunning design to AI innovation and cloud solutions, these projects showcase the best of our community &#x1F3C6;&#xA;Check them out: umbra.co/3Oq6hY3&#xA;&#xA;#Umbraco&#xA;&#xA;]]></description>
                    <pubDate>Tue, 07 Apr 2026 14:43:09 Z</pubDate>
                        <category>bluesky</category>
                        <category>social</category>
                        <category>hq</category>
                </item>
                <item>
                    <guid>https://mattbrailsford.dev/why-umbraco-1740-is-a-big-deal-for-ai</guid>
                    <title>Why Umbraco 17.4.0 Is a Big Deal for AI</title>
                    <link>https://mattbrailsford.dev/why-umbraco-1740-is-a-big-deal-for-ai</link>
                    <description><![CDATA[If you told most Umbraco developers to get excited about a minor release, you&#x2019;d probably get a polite nod. Point releases aren&#x2019;t usually the ones...]]></description>
                    <pubDate>Tue, 07 Apr 2026 08:30:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://umbraco.com/blog/announcing-the-2026-umbraco-awards-nominees/</guid>
                    <title>Announcing the 2026 Umbraco Awards Nominees &#x1F3C6;</title>
                    <link>https://umbraco.com/blog/announcing-the-2026-umbraco-awards-nominees/</link>
                    <description><![CDATA[The jury has nailed it down to the very best of each category - check out the impressive Umbraco Award 2026 Nominees &#x1F3C6;]]></description>
                    <pubDate>Tue, 07 Apr 2026 00:00:00 Z</pubDate>
                        <category>hq</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://skrift.io/issues/#126</guid>
                    <title>Skrift Issue #126</title>
                    <link>https://skrift.io/issues/#126</link>
                    <description><![CDATA[Featuring guest posts by Bernadet Goey on &quot;Admin Only property using Granular Permissions in Umbraco 17&quot; and Dirk Seefeld on &quot;PostgreSQL Support for Umbraco&quot;]]></description>
                    <pubDate>Tue, 07 Apr 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                        <category>skrift</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.schema2yaml</guid>
                    <title>SplatDev.Umbraco.Plugins.Schema2Yaml</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.schema2yaml</link>
                    <description><![CDATA[An Umbraco plugin that exports your existing Umbraco schema and content to YAML format. Exports DataTypes, DocumentTypes, Media Types, Templates, Content, Media, Languages, Dictionary Items, Members, and Users to a declarative Infrastructure-as-Code YAML file. Supports Umbraco 13&#x2013;17.]]></description>
                    <pubDate>Sun, 05 Apr 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://github.com/skybrud/Skybrud.Umbraco.Redirects/releases/tag/v17.0.4</guid>
                    <title>Skybrud.Umbraco.Redirects 17.0.4</title>
                    <link>https://github.com/skybrud/Skybrud.Umbraco.Redirects/releases/tag/v17.0.4</link>
                    <description><![CDATA[Award winning redirects manager for Umbraco.]]></description>
                    <pubDate>Fri, 03 Apr 2026 23:19:02 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                </item>
                <item>
                    <guid>https://umbracocommunity.social/@umbracospark/116335310919405813</guid>
                    <title>Umbraco Spark 2026 is a wrap!</title>
                    <link>https://umbracocommunity.social/@umbracospark/116335310919405813</link>
                    <description><![CDATA[Umbraco Spark 2026 is a wrap! &#x26A1;What a fantastic day &#x2014; full of inspiring sessions, thoughtful conversations and everything that makes this community so special.Huge thanks to everyone who made it happen &#x1F49B;&#x1F3A5; Highlights video attached &#x2014; take a look!&#x1F4DD; Plus, all the conference buzz&#x2014;read our blog: https://gibe.digital/blog/spark-2026-highlights-code-community-creativity/ &#x1F4C5; Save the date: Friday 19th March 2027&#x1F39F; Tickets go on sale November 2026#umbracospark #umbraco #community #webevents #opensource]]></description>
                    <pubDate>Thu, 02 Apr 2026 13:20:50 Z</pubDate>
                        <category>community</category>
                        <category>social</category>
                        <category>mastodon</category>
                </item>
                <item>
                    <guid>https://mattbrailsford.dev/umbraco-ai-prompts-template-syntax-and-variables</guid>
                    <title>Umbraco AI Prompts: Template Syntax and Variables</title>
                    <link>https://mattbrailsford.dev/umbraco-ai-prompts-template-syntax-and-variables</link>
                    <description><![CDATA[Following on from my Introducing Umbraco AI post, I wanted to dig deeper into one of the add-on packages that I think has the most immediately...]]></description>
                    <pubDate>Thu, 02 Apr 2026 08:30:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://github.com/umbraco/Announcements/issues/30</guid>
                    <title>[Breaking change]: Casing on EF Core code constructs</title>
                    <link>https://github.com/umbraco/Announcements/issues/30</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Thu, 02 Apr 2026 07:34:59 Z</pubDate>
                        <category>hq</category>
                        <category>announcement</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/our.umbraco.postgresql</guid>
                    <title>Our.Umbraco.PostgreSql</title>
                    <link>https://marketplace.umbraco.com/package/our.umbraco.postgresql</link>
                    <description><![CDATA[Adds support for PostgreSQL to Umbraco CMS.]]></description>
                    <pubDate>Thu, 02 Apr 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.examine.openxml</guid>
                    <title>Umbraco.Community.Examine.OpenXml</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.examine.openxml</link>
                    <description><![CDATA[Extracts text content from OpenXml documents (.docx, .pptx, .xlsx) uploaded to the Umbraco media library and indexes it using Examine, making Office document content fully searchable.]]></description>
                    <pubDate>Thu, 02 Apr 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://jcdc.dev/blog/umbraco-spark-2026</guid>
                    <title>Umbraco Spark 2026</title>
                    <link>https://jcdc.dev/blog/umbraco-spark-2026</link>
                    <description><![CDATA[My notes and reflections from Umbraco Spark 2026 in Bristol. Covering every talk from Umbraco Search and backoffice collaboration to AI, cloud hosting and community.]]></description>
                    <pubDate>Tue, 31 Mar 2026 21:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://www.linkedin.com/posts/developerlee_merchello-documentation-share-7444728952901877760-Oz7Y/?utm_source=share&amp;utm_medium=member_desktop&amp;rcm=ACoAAABj9KwBjr581HKBv-M3TbQu69Ia79rmfPw</guid>
                    <title>Merchello v17 Starter Site Template now available</title>
                    <link>https://www.linkedin.com/posts/developerlee_merchello-documentation-share-7444728952901877760-Oz7Y/?utm_source=share&amp;utm_medium=member_desktop&amp;rcm=ACoAAABj9KwBjr581HKBv-M3TbQu69Ia79rmfPw</link>
                    <description><![CDATA[Merchello Starter Site Template]]></description>
                    <pubDate>Tue, 31 Mar 2026 13:23:34 Z</pubDate>
                        <category>community</category>
                        <category>linkedin</category>
                        <category>social</category>
                </item>
                <item>
                    <guid>https://www.linkedin.com/posts/adamshallcross_just-thought-i-would-share-a-sneakpeek-of-ugcPost-7444666108776873986-lvMW/?utm_source=share&amp;utm_medium=member_desktop&amp;rcm=ACoAAEZMLBQB0B-TxZjsCmPSm4mFHU6Y9pFI12s</guid>
                    <title>AI agent workflows sneak peek</title>
                    <link>https://www.linkedin.com/posts/adamshallcross_just-thought-i-would-share-a-sneakpeek-of-ugcPost-7444666108776873986-lvMW/?utm_source=share&amp;utm_medium=member_desktop&amp;rcm=ACoAAEZMLBQB0B-TxZjsCmPSm4mFHU6Y9pFI12s</link>
                    <description><![CDATA[Post | LinkedIn]]></description>
                    <pubDate>Tue, 31 Mar 2026 09:35:28 Z</pubDate>
                        <category>social</category>
                        <category>linkedin</category>
                        <category>community</category>
                </item>
                <item>
                    <guid>https://www.linkedin.com/pulse/finding-my-spark-through-community-spinbox-digital-q5sme/</guid>
                    <title>Finding my Spark through Community</title>
                    <link>https://www.linkedin.com/pulse/finding-my-spark-through-community-spinbox-digital-q5sme/</link>
                    <description><![CDATA[(6) Finding my Spark through Community | LinkedIn]]></description>
                    <pubDate>Tue, 31 Mar 2026 08:55:52 Z</pubDate>
                        <category>community</category>
                        <category>social</category>
                        <category>linkedin</category>
                </item>
                <item>
                    <guid>https://github.com/Ambertvu/Umbraco.Community.IconPicker/releases/tag/17.0.0</guid>
                    <title>V17 of IconPicker has been released</title>
                    <link>https://github.com/Ambertvu/Umbraco.Community.IconPicker/releases/tag/17.0.0</link>
                    <description><![CDATA[https://github.com/Ambertvu/Umbraco.Community.IconPicker/releases/tag/17.0.0&#xA;V17 of IconPicker has been released. &#xA;- Add an sprite containing all the SVG&#x27;s&#xA;- Pick these in the backoffice&#xA;- Render them as SVG in the frontend, so you can apply styles and effects!]]></description>
                    <pubDate>Tue, 31 Mar 2026 08:26:38 Z</pubDate>
                        <category>package</category>
                        <category>community</category>
                </item>
                <item>
                    <guid>https://www.spreaker.com/episode/live-from-spark-2026-ai-play-and-the-human-in-the-loop--71006607</guid>
                    <title>Live from Spark 2026: AI, Play and the Human in the Loop</title>
                    <link>https://www.spreaker.com/episode/live-from-spark-2026-ai-play-and-the-human-in-the-loop--71006607</link>
                    <description><![CDATA[Live from the Umbraco Spark Innovation Conference in Bristol! Emma, Laura and Lotte were joined by Phil Whittaker, AI Staff Engineer at Umbraco HQ - someone who&#x27;s been thinking and talking about AI in development for longer than most. Together we talk about play as a superpower for developer learning, what returning from maternity leave looks like in an AI-transformed workplace, why developers approaching retirement are finding a second wind, and why augmentation beats automation every time.&#xA0;&#xA0;&lt;br /&gt;&#xA0;&#xA0;&lt;br /&gt;A massive thank you to our live audience for missing out on the sunshine and making it so fun to record!&#xA0;&#xA0;&lt;br /&gt;&#xA0;&#xA0;&lt;br /&gt;Links:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Umbraco Spark: &lt;a href=&quot;https://umbracospark.com/&quot; target=&quot;_blank&quot; rel=&quot;noreferrer noopener&quot;&gt;https://umbracospark.com/&lt;/a&gt; &#xA0;&lt;/li&gt;&lt;li&gt;Phil Whittaker&#x27;s blog: &lt;a href=&quot;https://dev.to/phil-whittaker&quot; target=&quot;_blank&quot; rel=&quot;noreferrer noopener&quot;&gt;https://dev.to/phil-whittaker&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;]]></description>
                    <pubDate>Tue, 31 Mar 2026 06:01:17 Z</pubDate>
                        <category>community</category>
                        <category>podcast</category>
                </item>
                <item>
                    <guid>https://owain.codes/blog/2026/march/optimizing-umbraco-member-pagination-from-slow-to-lightning-fast/</guid>
                    <title>Optimizing Umbraco Member Pagination From Slow to Lightning Fast</title>
                    <link>https://owain.codes/blog/2026/march/optimizing-umbraco-member-pagination-from-slow-to-lightning-fast/</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Tue, 31 Mar 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/utpro.feature.filemanager</guid>
                    <title>uTPro.Feature.FileManager</title>
                    <link>https://marketplace.umbraco.com/package/utpro.feature.filemanager</link>
                    <description><![CDATA[A powerful file management dashboard for Umbraco 16&#x2B; backoffice. Browse, upload, download, edit (with Monaco code editor), preview media, rename, delete, extract ZIP, and import files via URL. Features Windows Explorer-style navigation, role-based access control (Admin/Sensitive Data/Media), pagination for large directories, and URL state persistence. Zero configuration required.]]></description>
                    <pubDate>Tue, 31 Mar 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/phases.umbraco.community.tiptap.rte.emoji</guid>
                    <title>Phases.Umbraco.Community.Tiptap.Rte.Emoji</title>
                    <link>https://marketplace.umbraco.com/package/phases.umbraco.community.tiptap.rte.emoji</link>
                    <description><![CDATA[Adds a simple emoji picker to the Umbraco TipTap Rich Text Editor. Insert emojis directly into content using a searchable picker in the backoffice.]]></description>
                    <pubDate>Tue, 31 Mar 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.tiptap.markdownimport</guid>
                    <title>Umbraco.Community.TipTap.MarkdownImport</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.tiptap.markdownimport</link>
                    <description><![CDATA[Adds a Paste Markdown action to the Umbraco TipTap Rich Text Editor so editors can import Markdown into rich text fields as HTML content.]]></description>
                    <pubDate>Tue, 31 Mar 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://owaincodes.uksouth01.umbraco.io/blog/2026/march/optimizing-umbraco-member-pagination-from-slow-to-lightning-fast/</guid>
                    <title>Optimizing Umbraco Member Pagination From Slow to Lightning Fast</title>
                    <link>https://owaincodes.uksouth01.umbraco.io/blog/2026/march/optimizing-umbraco-member-pagination-from-slow-to-lightning-fast/</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Tue, 31 Mar 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://33b6c16b-3387-4d68-9090-4cb1f20ea7b3.azurewebsites.nethttps://owain.codes/blog/2026/march/optimizing-umbraco-member-pagination-from-slow-to-lightning-fast/</guid>
                    <title>Optimizing Umbraco Member Pagination From Slow to Lightning Fast</title>
                    <link>https://33b6c16b-3387-4d68-9090-4cb1f20ea7b3.azurewebsites.nethttps://owain.codes/blog/2026/march/optimizing-umbraco-member-pagination-from-slow-to-lightning-fast/</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Tue, 31 Mar 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://kjac.dev/posts/searching-file-content-with-umbraco-search/</guid>
                    <title>Searching file content with Umbraco Search</title>
                    <link>https://kjac.dev/posts/searching-file-content-with-umbraco-search/</link>
                    <description><![CDATA[Introducing a package for searching file content with Umbraco Search.]]></description>
                    <pubDate>Mon, 30 Mar 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.environmentindicator</guid>
                    <title>Umbraco.Community.EnvironmentIndicator</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.environmentindicator</link>
                    <description><![CDATA[Makes Umbraco backoffice environments stand out with colored favicons and environment name badges in the header.]]></description>
                    <pubDate>Mon, 30 Mar 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.yaml2schema</guid>
                    <title>SplatDev.Umbraco.Plugins.Yaml2Schema</title>
                    <link>https://marketplace.umbraco.com/package/splatdev.umbraco.plugins.yaml2schema</link>
                    <description><![CDATA[A declarative, Infrastructure-as-Code style plugin for Umbraco 17 that enables programmatic creation of DataTypes, DocumentTypes, Templates, and Content from a YAML configuration file. Define your entire Umbraco structure in YAML &#x2014; the plugin builds it automatically on startup.]]></description>
                    <pubDate>Mon, 30 Mar 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.datatypecleanup</guid>
                    <title>Umbraco.Community.DataTypeCleanup</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.datatypecleanup</link>
                    <description><![CDATA[Clean up orphan data types, merge duplicates, and organize data types into folders by editor.]]></description>
                    <pubDate>Mon, 30 Mar 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://www.nuget.org/packages/Umbraco.Community.ContentLock</guid>
                    <title>Content Lock 17.1.0 - aka the WebRTC Audio Calling edition</title>
                    <link>https://www.nuget.org/packages/Umbraco.Community.ContentLock</link>
                    <description><![CDATA[Content Lock 17.1.0 - aka the WebRTC Audio Calling edition&#xA;Latest release adds in audio calling to other logged in users of the backoffice with nothing to install.&#xA;So that quick call to another editor to hurry up and unlock the homenode so you can get the press release out before lunch can be done without having to remember what Microsoft Teams account you need to login to&#xA;&#xA;Docs Site&#xA;https://warrenbuckley.github.io/Umbraco.Community.ContentLock/&#xA;&#xA;Marketplace&#xA;https://marketplace.umbraco.com/package/umbraco.community.contentlock&#xA;&#xA;Nuget&#xA;https://www.nuget.org/packages/Umbraco.Community.ContentLock]]></description>
                    <pubDate>Fri, 27 Mar 2026 12:30:04 Z</pubDate>
                        <category>package</category>
                        <category>community</category>
                </item>
                <item>
                    <guid>https://www.youtube.com/watch?v=-b3HkTedXcA</guid>
                    <title>umbraCoffee - Spring Sips</title>
                    <link>https://www.youtube.com/watch?v=-b3HkTedXcA</link>
                    <description><![CDATA[Welcome to your monthly dose of #umbraCoffee&#x200B;&#x200B;&#x200B;&#x200B;&#x200B;&#x200B;&#x200B;&#x200B;&#x200B;&#x200B;&#x200B;&#x200B;! Your hosts - Marcin and Callum - together with their guest(s) will drive through all of the community news and happenings in the Umbraco world. So... grab a cuppa, join us LIVE and enjoy!&#xA;&#xA;This time we&#x27;re joined by Umbraco Hacker, Maker and Do&#x27;er - Warren Buckley - to talk about everything Umbraco from the past moth.&#xA;&#xA;See ya?!&#xA;&#xA;---&#xA;&#x2615; Wanna buy us a coffee/pizza/donuts?&#xA;https://www.buymeacoffee.com/umbracoffee&#xA;---&#xA;&#xA;Notes:&#xA;// ToDo:]]></description>
                    <pubDate>Fri, 27 Mar 2026 08:51:45 Z</pubDate>
                        <category>community</category>
                        <category>youtube</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/utpro.feature.auditlog</guid>
                    <title>uTPro.Feature.AuditLog</title>
                    <link>https://marketplace.umbraco.com/package/utpro.feature.auditlog</link>
                    <description><![CDATA[Audit Log viewer dashboard for Umbraco 16&#x2B; backoffice. Browse umbracoAudit and umbracoLog tables with filtering, search, and pagination.]]></description>
                    <pubDate>Fri, 27 Mar 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://mattbrailsford.dev/understanding-contexts-in-umbraco-ai</guid>
                    <title>Understanding Contexts in Umbraco AI</title>
                    <link>https://mattbrailsford.dev/understanding-contexts-in-umbraco-ai</link>
                    <description><![CDATA[In my introductory post, I gave a high-level overview of how Umbraco AI is structured &#x2014; providers, connections, profiles, and contexts. Of those,...]]></description>
                    <pubDate>Fri, 27 Mar 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.propertyinfo</guid>
                    <title>Umbraco.Community.PropertyInfo</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.propertyinfo</link>
                    <description><![CDATA[Package Description]]></description>
                    <pubDate>Fri, 27 Mar 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://www.youtube.com/watch?v=HLV0FeRKhNI</guid>
                    <title>Early concepts for Reuse Content of Blocks</title>
                    <link>https://www.youtube.com/watch?v=HLV0FeRKhNI</link>
                    <description><![CDATA[(4) Early concepts for Reuse Content of Blocks - YouTube]]></description>
                    <pubDate>Thu, 26 Mar 2026 13:08:18 Z</pubDate>
                        <category>community</category>
                        <category>youtube</category>
                        <category>social</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/modgift.umbraco.croninput</guid>
                    <title>Modgift.Umbraco.CronInput</title>
                    <link>https://marketplace.umbraco.com/package/modgift.umbraco.croninput</link>
                    <description><![CDATA[A property editor for Umbraco that provides a cron expression input with real-time human-readable descriptions. As the user types a cron expression, a label beneath the input instantly translates it into plain language. Includes an optional validation setting to prevent publishing without a valid expression.]]></description>
                    <pubDate>Thu, 26 Mar 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://umbraco.com/blog/announcing-the-umbraco-in-ai-community-team-the-ai-in-umbraco-advisory-board/</guid>
                    <title>Announcing the Umbraco in AI Community Team &amp; the AI in Umbraco Advisory Board</title>
                    <link>https://umbraco.com/blog/announcing-the-umbraco-in-ai-community-team-the-ai-in-umbraco-advisory-board/</link>
                    <description><![CDATA[Meet the 27 experts joining the Umbraco in AI Community Team and Advisory Board to help shape the future of AI tools and editor experiences within Umbraco.]]></description>
                    <pubDate>Thu, 26 Mar 2026 00:00:00 Z</pubDate>
                        <category>hq</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://www.nevitech.co.uk/blog/building-an-ai-powered-log-analyser-for-umbraco-at-the-spark-hackathon/</guid>
                    <title>Building an AI-Powered Log Analyser for Umbraco at the Spark Hackathon</title>
                    <link>https://www.nevitech.co.uk/blog/building-an-ai-powered-log-analyser-for-umbraco-at-the-spark-hackathon/</link>
                    <description><![CDATA[A look at how I built AI.LogAnalyser at the  @umbracospark.bsky.social Hackathon - an open-source package that adds one-click AI analysis to the Umbraco backoffice log viewer.  Powered by any AI provider via Umbraco AI.&#xA;&#xA;www.nevitech.co.uk/blog/buildin...&#xA;&#xA;#umbraco #ai #package&#xA;&#xA;]]></description>
                    <pubDate>Wed, 25 Mar 2026 09:50:08 Z</pubDate>
                        <category>blog</category>
                        <category>community</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/rescope.uastro</guid>
                    <title>Rescope.uAstro</title>
                    <link>https://marketplace.umbraco.com/package/rescope.uastro</link>
                    <description><![CDATA[Automatically build and serve static Astro sites within Umbraco]]></description>
                    <pubDate>Wed, 25 Mar 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/rescope.contentdelivery</guid>
                    <title>Rescope.ContentDelivery</title>
                    <link>https://marketplace.umbraco.com/package/rescope.contentdelivery</link>
                    <description><![CDATA[Improves swagger definitions for use with typed client generators]]></description>
                    <pubDate>Wed, 25 Mar 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.updoc</guid>
                    <title>Umbraco.Community.UpDoc</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.updoc</link>
                    <description><![CDATA[Create Umbraco documents from external sources (PDF, web pages, markdown) using configurable extraction workflows with rule-based field mapping.]]></description>
                    <pubDate>Wed, 25 Mar 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/metamateai</guid>
                    <title>MetaMateAI</title>
                    <link>https://marketplace.umbraco.com/package/metamateai</link>
                    <description><![CDATA[Umbraco plugin for generating creative meta title and meta description values for pages with missing metadata.]]></description>
                    <pubDate>Tue, 24 Mar 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://owain.codes/blog/2026/march/gitkraken-cli-beginners-guide/</guid>
                    <title>GitKraken CLI Beginner&#x27;s Guide: A Better Git CLI for Developers</title>
                    <link>https://owain.codes/blog/2026/march/gitkraken-cli-beginners-guide/</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Tue, 24 Mar 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://www.nathanielnunes.com/blog/umbraco-in-action-introduction-to-cms-for-students</guid>
                    <title>Umbraco In Action - Introduction to CMS for students</title>
                    <link>https://www.nathanielnunes.com/blog/umbraco-in-action-introduction-to-cms-for-students</link>
                    <description><![CDATA[Just put out a blog &#x2B; session recording from a talk I did with Coders Club students at Don Bosco College of Engineering, Fatorda.&#xA;&#xA;Started simple with &#x201C;what is a CMS&#x201D; before jumping into demos with Umbraco, headless setup with Next.js, and even a bit of AI.&#xA;&#xA;Good questions from the students, especially around WordPress vs Umbraco &#x1F440;&#xA;&#xA;Blog Post: https://www.nathanielnunes.com/blog/umbraco-in-action-introduction-to-cms-for-students&#xA;Video: https://youtu.be/znH8tnedIQg]]></description>
                    <pubDate>Mon, 23 Mar 2026 06:57:07 Z</pubDate>
                        <category>blog</category>
                        <category>community</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/conzent.umbraco</guid>
                    <title>Conzent.Umbraco</title>
                    <link>https://marketplace.umbraco.com/package/conzent.umbraco</link>
                    <description><![CDATA[GDPR, CCPA &amp; ePrivacy compliant cookie consent banner for Umbraco. IAB TCF v2.3 and Google CMP Certified. Supports Conzent Cloud and self-hosted OCI.]]></description>
                    <pubDate>Mon, 23 Mar 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/modgift.umbraco.datagrid</guid>
                    <title>Modgift.Umbraco.DataGrid</title>
                    <link>https://marketplace.umbraco.com/package/modgift.umbraco.datagrid</link>
                    <description><![CDATA[A multiple column data editor property editor for Umbraco with strongly-typed DataGrid model.]]></description>
                    <pubDate>Sat, 21 Mar 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/growcreate.schemagenerator.deployaddon</guid>
                    <title>Growcreate.SchemaGenerator.DeployAddon</title>
                    <link>https://marketplace.umbraco.com/package/growcreate.schemagenerator.deployaddon</link>
                    <description><![CDATA[Schema Generator for Umbraco to create and render schema objects. Map document type properties to schema properties and allow editors to populate additional schemas.]]></description>
                    <pubDate>Fri, 20 Mar 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/jumoo.translationmanager.cleanup</guid>
                    <title>Jumoo.TranslationManager.Cleanup</title>
                    <link>https://marketplace.umbraco.com/package/jumoo.translationmanager.cleanup</link>
                    <description><![CDATA[Prodvides health checks to clean up archived jobs and nodes.]]></description>
                    <pubDate>Fri, 20 Mar 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/growcreate.schemagenerator.usyncaddon</guid>
                    <title>Growcreate.SchemaGenerator.uSyncAddon</title>
                    <link>https://marketplace.umbraco.com/package/growcreate.schemagenerator.usyncaddon</link>
                    <description><![CDATA[Schema Generator for Umbraco to create and render schema objects. Map document type properties to schema properties and allow editors to populate additional schemas.]]></description>
                    <pubDate>Fri, 20 Mar 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.ai.loganalyser</guid>
                    <title>Umbraco.Community.AI.LogAnalyser</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.ai.loganalyser</link>
                    <description><![CDATA[Adds AI-powered log analysis to the Umbraco backoffice log viewer. Analyse any log entry with one click using your configured AI provider via Umbraco.AI.]]></description>
                    <pubDate>Fri, 20 Mar 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/growcreate.schemagenerator.core</guid>
                    <title>Growcreate.SchemaGenerator.Core</title>
                    <link>https://marketplace.umbraco.com/package/growcreate.schemagenerator.core</link>
                    <description><![CDATA[Schema Generator for Umbraco to create and render schema objects. Map document type properties to schema properties and allow editors to populate additional schemas.]]></description>
                    <pubDate>Fri, 20 Mar 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.deliveryapimodelmapper</guid>
                    <title>Umbraco.Community.DeliveryApiModelMapper</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.deliveryapimodelmapper</link>
                    <description><![CDATA[This package allows you to create custom models which will get ouput in the Delivery API response as a custom &quot;model&quot; property.]]></description>
                    <pubDate>Fri, 20 Mar 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://www.debasish.tech/blogs/developer-s-guide-to-creating-a-custom-umbraco-17-backoffice-dashboard/</guid>
                    <title>Developer&#x2019;s Guide to Creating a Custom Umbraco 17 Backoffice Dashboard</title>
                    <link>https://www.debasish.tech/blogs/developer-s-guide-to-creating-a-custom-umbraco-17-backoffice-dashboard/</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Fri, 20 Mar 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://dev.to/cultiv/setting-up-a-new-umbraco-package-dev-environment-with-umbracoai-3iac</guid>
                    <title>Setting Up a New Umbraco Package Dev Environment with Umbraco.AI</title>
                    <link>https://dev.to/cultiv/setting-up-a-new-umbraco-package-dev-environment-with-umbracoai-3iac</link>
                    <description><![CDATA[&lt;p&gt;This guide walks through setting up a new Umbraco package project called &lt;code&gt;Umbraco.Community.AI.Woowoo&lt;/code&gt; that extends &lt;a href=&quot;https://umbraco.com/marketplace/category/ai/&quot; rel=&quot;noopener noreferrer&quot;&gt;Umbraco.AI&lt;/a&gt;. Rather than starting from scratch with a blank solution, the goal is a proper package structure from day one: the right project layout, a frontend build pipeline, uSync, GitHub Actions for NuGet publishing, the works.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;That&#x27;s where &lt;a href=&quot;https://github.com/LottePitcher/opinionated-package-starter&quot; rel=&quot;noopener noreferrer&quot;&gt;Lotte&#x27;s Opinionated Package Starter Template&lt;/a&gt; comes in. Lotte has done the hard work of figuring out what a well-structured Umbraco package solution should look like, and turned it into a &lt;code&gt;dotnet new&lt;/code&gt; template. Pair that with Matt Brailsford&#x27;s &lt;a href=&quot;https://mattbrailsford.dev/umbraco-ai-kitchen-sink-install&quot; rel=&quot;noopener noreferrer&quot;&gt;Umbraco.AI Kitchen Sink install guide&lt;/a&gt;, and you have everything you need to go from zero to a fully wired-up Umbraco.AI development environment.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;This post walks through the full setup, including the Linux-specific gotcha to watch out for.&lt;/p&gt;&#xA;&#xA;&#xA;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  Prerequisites&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Before starting, make sure you have:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;strong&gt;.NET 10 SDK&lt;/strong&gt; -- Umbraco 17 targets .NET 10&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;strong&gt;Node.js and npm&lt;/strong&gt; -- the package project uses Vite and TypeScript for its frontend&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;strong&gt;A GitHub account&lt;/strong&gt; -- the template wires up a GitHub remote and includes GitHub Actions for NuGet publishing&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&#xA;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  Step 1: Install the template&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Install the package starter template from NuGet:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight shell&quot;&gt;&lt;code&gt;dotnet new &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;Umbraco.Community.Templates.PackageStarter&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;You should see output ending with something like:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight plaintext&quot;&gt;&lt;code&gt;Success: Umbraco.Community.Templates.PackageStarter::X.X.X installed the following templates:&#xA;  umbracopackagestarter&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;What does this template give you?&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;When you scaffold from it, you get a complete two-project solution:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;code&gt;src/AI.Woowoo/&lt;/code&gt; -- the package project, with Vite &#x2B; TypeScript frontend (via the &lt;code&gt;umbraco-extension&lt;/code&gt; template) and a NuGet-configured &lt;code&gt;.csproj&lt;/code&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;code&gt;src/AI.Woowoo.TestSite/&lt;/code&gt; -- an Umbraco 17 test site with uSync pre-configured&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;code&gt;src/AI.Woowoo.sln&lt;/code&gt; -- the solution file, with the TestSite already referencing the package project&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;code&gt;.github/workflows/release.yml&lt;/code&gt; -- a GitHub Action that publishes to NuGet when you push a version tag&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;code&gt;umbraco-marketplace.json&lt;/code&gt;, README stubs, issue templates, and an MIT &lt;code&gt;LICENSE&lt;/code&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;That&#x27;s a solid foundation for package development, covering all the scaffolding that would otherwise take hours to set up from scratch.&lt;/p&gt;&#xA;&#xA;&#xA;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  Step 2: Scaffold the solution&#xA;&lt;/h2&gt;&#xA;&#xA;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight shell&quot;&gt;&lt;code&gt;dotnet new umbracopackagestarter &lt;span class=&quot;nt&quot;&gt;-n&lt;/span&gt; AI.Woowoo &lt;span class=&quot;nt&quot;&gt;-an&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Your Name&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-gu&lt;/span&gt; YourGitHubUsername &lt;span class=&quot;nt&quot;&gt;-gr&lt;/span&gt; Umbraco.Community.AI.Woowoo &lt;span class=&quot;nt&quot;&gt;--allow-scripts&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;yes&lt;/span&gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;What each parameter does:&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;table-wrapper-paragraph&quot;&gt;&lt;table&gt;&#xA;&lt;thead&gt;&#xA;&lt;tr&gt;&#xA;&lt;th&gt;Parameter&lt;/th&gt;&#xA;&lt;th&gt;What it does&lt;/th&gt;&#xA;&lt;/tr&gt;&#xA;&lt;/thead&gt;&#xA;&lt;tbody&gt;&#xA;&lt;tr&gt;&#xA;&lt;td&gt;&lt;code&gt;-n AI.Woowoo&lt;/code&gt;&lt;/td&gt;&#xA;&lt;td&gt;The base name for the solution. The template prepends &lt;code&gt;Umbraco.Community.&lt;/code&gt;, so the NuGet package ID becomes &lt;code&gt;Umbraco.Community.AI.Woowoo&lt;/code&gt;&#xA;&lt;/td&gt;&#xA;&lt;/tr&gt;&#xA;&lt;tr&gt;&#xA;&lt;td&gt;&lt;code&gt;-an &quot;Your Name&quot;&lt;/code&gt;&lt;/td&gt;&#xA;&lt;td&gt;Author name, used in the &lt;code&gt;.csproj&lt;/code&gt; and marketplace metadata&lt;/td&gt;&#xA;&lt;/tr&gt;&#xA;&lt;tr&gt;&#xA;&lt;td&gt;&lt;code&gt;-gu YourGitHubUsername&lt;/code&gt;&lt;/td&gt;&#xA;&lt;td&gt;Your GitHub username, used to construct the repo URL&lt;/td&gt;&#xA;&lt;/tr&gt;&#xA;&lt;tr&gt;&#xA;&lt;td&gt;&lt;code&gt;-gr Umbraco.Community.AI.Woowoo&lt;/code&gt;&lt;/td&gt;&#xA;&lt;td&gt;The GitHub repository name&lt;/td&gt;&#xA;&lt;/tr&gt;&#xA;&lt;tr&gt;&#xA;&lt;td&gt;&lt;code&gt;--allow-scripts yes&lt;/code&gt;&lt;/td&gt;&#xA;&lt;td&gt;Bypasses the security prompt for the post-creation script (&lt;code&gt;setup.cmd&lt;/code&gt;), which runs &lt;code&gt;npm install&lt;/code&gt; as part of the &lt;code&gt;umbraco-extension&lt;/code&gt; template setup&lt;/td&gt;&#xA;&lt;/tr&gt;&#xA;&lt;/tbody&gt;&#xA;&lt;/table&gt;&lt;/div&gt;&#xA;&#xA;&lt;p&gt;This will take a few minutes -- &lt;code&gt;npm install&lt;/code&gt; runs as part of the setup. Wait for the &quot;All done!&quot; message.&lt;/p&gt;&#xA;&#xA;&#xA;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  Step 3: The Linux/macOS gotcha -- &lt;code&gt;setup.cmd&lt;/code&gt; won&#x27;t run&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;If you&#x27;re on Windows, you can skip this section.&lt;/strong&gt; The template&#x27;s &lt;code&gt;setup.cmd&lt;/code&gt; script will have run fine and your solution is ready. Jump straight to Step 4.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&#xA;&lt;p&gt;On Linux and macOS, the &lt;code&gt;setup.cmd&lt;/code&gt; post-creation script fails with &quot;Permission denied&quot; because it&#x27;s a Windows batch file. The template &lt;em&gt;files&lt;/em&gt; are all created correctly -- the script just doesn&#x27;t run, so the git repository, the frontend scaffolding, the solution wiring, and a few other things need to be done manually.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Here&#x27;s everything the script would have done, translated into commands you can run:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight shell&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Initialise the git repository&lt;/span&gt;&#xA;&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;AI.Woowoo&#xA;git init&#xA;git branch &lt;span class=&quot;nt&quot;&gt;-M&lt;/span&gt; main&#xA;git remote add origin https://github.com/YourGitHubUsername/Umbraco.Community.AI.Woowoo.git&#xA;&#xA;&lt;span class=&quot;c&quot;&gt;# Make sure you have the latest Umbraco dotnet templates&lt;/span&gt;&#xA;dotnet new &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;Umbraco.Templates &lt;span class=&quot;nt&quot;&gt;--force&lt;/span&gt;&#xA;&#xA;&lt;span class=&quot;c&quot;&gt;# Scaffold the package project inside src/&lt;/span&gt;&#xA;&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;src&#xA;dotnet new umbraco-extension &lt;span class=&quot;nt&quot;&gt;-n&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;AI.Woowoo&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--site-domain&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;https://localhost:44361&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--include-example&lt;/span&gt;&#xA;&#xA;&lt;span class=&quot;c&quot;&gt;# The template creates two .csproj files -- swap them so the NuGet-configured one is active&lt;/span&gt;&#xA;&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;AI.Woowoo&#xA;&lt;span class=&quot;nb&quot;&gt;rm &lt;/span&gt;AI.Woowoo.csproj&#xA;&lt;span class=&quot;nb&quot;&gt;mv &lt;/span&gt;AI.Woowoo_nuget.csproj AI.Woowoo.csproj&#xA;&#xA;&lt;span class=&quot;c&quot;&gt;# Wire everything up in the solution&lt;/span&gt;&#xA;&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; ..&#xA;dotnet sln add &lt;span class=&quot;s2&quot;&gt;&quot;AI.Woowoo&quot;&lt;/span&gt;&#xA;dotnet add &lt;span class=&quot;s2&quot;&gt;&quot;AI.Woowoo.TestSite/AI.Woowoo.TestSite.csproj&quot;&lt;/span&gt; reference &lt;span class=&quot;s2&quot;&gt;&quot;AI.Woowoo/AI.Woowoo.csproj&quot;&lt;/span&gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; The repo root also contains a &lt;code&gt;setup.mjs&lt;/code&gt; file -- a Node.js replacement for &lt;code&gt;setup.cmd&lt;/code&gt; that works cross-platform. If it&#x27;s present, running &lt;code&gt;node setup.mjs&lt;/code&gt; handles all the steps above.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&#xA;&#xA;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  Step 4: Build the frontend &amp;amp; verify the base site&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Before layering anything on top, confirm the scaffolded solution actually works. Build the frontend assets first:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight shell&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;src/AI.Woowoo/Client&#xA;npm &lt;span class=&quot;nb&quot;&gt;install&#xA;&lt;/span&gt;npm run build&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;You should see Vite output with files written to &lt;code&gt;dist/&lt;/code&gt;. Now start the TestSite:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight shell&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; ../../AI.Woowoo.TestSite&#xA;dotnet run&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;The &lt;code&gt;launchSettings.json&lt;/code&gt; included by the template automatically sets &lt;code&gt;ASPNETCORE_ENVIRONMENT=Development&lt;/code&gt;, so you don&#x27;t need to set it yourself. On first run, Umbraco installs itself unattended -- watch the terminal output for the URL (typically &lt;code&gt;https://localhost:44331&lt;/code&gt; or similar).&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Log in with the pre-configured credentials from &lt;code&gt;appsettings.json&lt;/code&gt;:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;strong&gt;Email:&lt;/strong&gt; &lt;code&gt;admin@example.com&lt;/code&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;strong&gt;Password:&lt;/strong&gt; &lt;code&gt;1234567890&lt;/code&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;Check two things:&lt;/p&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Navigate to the &lt;strong&gt;Content&lt;/strong&gt; section -- an &quot;Example Dashboard&quot; should be there (this is the example added by the &lt;code&gt;--include-example&lt;/code&gt; flag in the &lt;code&gt;umbraco-extension&lt;/code&gt; template)&lt;/li&gt;&#xA;&lt;li&gt;Navigate to &lt;code&gt;/umbraco/swagger&lt;/code&gt; -- the &lt;strong&gt;Umbraco Management API&lt;/strong&gt; document should appear in the dropdown&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;p&gt;Once everything looks good, hit &lt;code&gt;Ctrl&#x2B;C&lt;/code&gt; to stop the site. You now have a clean, working base to build on.&lt;/p&gt;&#xA;&#xA;&#xA;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  Step 5: Add the Umbraco.AI packages&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;All the Umbraco.AI packages go into the TestSite project, not the package project. The package project stays clean -- it will only reference &lt;code&gt;Umbraco.AI&lt;/code&gt; (or specific Umbraco.AI interfaces) when actually needed for package code. The TestSite is the development host.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Run these from the repo root (&lt;code&gt;AI.Woowoo/&lt;/code&gt;):&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight shell&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# The Clean starter kit adds a demo content structure to the site&lt;/span&gt;&#xA;dotnet add &lt;span class=&quot;s2&quot;&gt;&quot;src/AI.Woowoo.TestSite&quot;&lt;/span&gt; package Clean&#xA;&#xA;&lt;span class=&quot;c&quot;&gt;# The core Umbraco.AI integration layer&lt;/span&gt;&#xA;dotnet add &lt;span class=&quot;s2&quot;&gt;&quot;src/AI.Woowoo.TestSite&quot;&lt;/span&gt; package Umbraco.AI&#xA;&#xA;&lt;span class=&quot;c&quot;&gt;# Addons&lt;/span&gt;&#xA;dotnet add &lt;span class=&quot;s2&quot;&gt;&quot;src/AI.Woowoo.TestSite&quot;&lt;/span&gt; package Umbraco.AI.Prompt&#xA;dotnet add &lt;span class=&quot;s2&quot;&gt;&quot;src/AI.Woowoo.TestSite&quot;&lt;/span&gt; package Umbraco.AI.Agent&#xA;dotnet add &lt;span class=&quot;s2&quot;&gt;&quot;src/AI.Woowoo.TestSite&quot;&lt;/span&gt; package Umbraco.AI.Agent.Copilot &lt;span class=&quot;nt&quot;&gt;--prerelease&lt;/span&gt;&#xA;&#xA;&lt;span class=&quot;c&quot;&gt;# AI providers&lt;/span&gt;&#xA;dotnet add &lt;span class=&quot;s2&quot;&gt;&quot;src/AI.Woowoo.TestSite&quot;&lt;/span&gt; package Umbraco.AI.Amazon&#xA;dotnet add &lt;span class=&quot;s2&quot;&gt;&quot;src/AI.Woowoo.TestSite&quot;&lt;/span&gt; package Umbraco.AI.Anthropic&#xA;dotnet add &lt;span class=&quot;s2&quot;&gt;&quot;src/AI.Woowoo.TestSite&quot;&lt;/span&gt; package Umbraco.AI.Google&#xA;dotnet add &lt;span class=&quot;s2&quot;&gt;&quot;src/AI.Woowoo.TestSite&quot;&lt;/span&gt; package Umbraco.AI.MicrosoftFoundry&#xA;dotnet add &lt;span class=&quot;s2&quot;&gt;&quot;src/AI.Woowoo.TestSite&quot;&lt;/span&gt; package Umbraco.AI.OpenAI&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;A couple of notes:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;code&gt;Umbraco.AI.Agent.Copilot&lt;/code&gt; requires &lt;code&gt;--prerelease&lt;/code&gt; because it&#x27;s still in alpha. The other packages are stable.&lt;/li&gt;&#xA;&lt;li&gt;All five provider packages (Amazon Bedrock, Anthropic, Google, Microsoft Foundry, OpenAI) are installed so the environment is ready for any AI provider you or contributors want to test against. The seed data in the next step only activates the OpenAI connection, but the others are configured and waiting.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;Check &lt;a href=&quot;https://mattbrailsford.dev/umbraco-ai-kitchen-sink-install&quot; rel=&quot;noopener noreferrer&quot;&gt;Matt&#x27;s install guide&lt;/a&gt; if you&#x27;re following along later -- version numbers may have moved on. The &lt;a href=&quot;https://github.com/umbraco/Umbraco.AI/tree/main/docs/public&quot; rel=&quot;noopener noreferrer&quot;&gt;Umbraco.AI documentation&lt;/a&gt; covers all the extensibility points in detail if you want to go further.&lt;/p&gt;&#xA;&#xA;&#xA;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  Step 6: Add the seed demo data&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Matt has a helpful GitHub Gist that seeds a full Umbraco.AI demo configuration: a connection, profile, context, prompts, and agents. It&#x27;s a self-registering C# file -- drop it in the project and it registers itself via Umbraco&#x27;s component system and seeds the data on first startup. It&#x27;s also idempotent, so safe to leave in place.&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight shell&quot;&gt;&lt;code&gt;curl &lt;span class=&quot;nt&quot;&gt;-o&lt;/span&gt; src/AI.Woowoo.TestSite/UmbracoAISeedData.cs &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;&#xA;  &lt;span class=&quot;s2&quot;&gt;&quot;https://gist.githubusercontent.com/mattbrailsford/199d0b45e926ffb122fa96467039bd90/raw/UmbracoAISeedData.cs?v=2&quot;&lt;/span&gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;h3&gt;&#xA;  &#xA;  &#xA;  API key (optional)&#xA;&lt;/h3&gt;&#xA;&#xA;&lt;p&gt;The seed data installs an OpenAI connection with a dummy key. The site runs fine without a real key -- all the AI configuration gets seeded into the backoffice, the connection just won&#x27;t be functional. Replace the key later through the Umbraco.AI section in the backoffice once everything is up and running.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Don&#x27;t have an OpenAI key? Google hands out free Gemini API keys via &lt;a href=&quot;https://aistudio.google.com/app/apikey&quot; rel=&quot;noopener noreferrer&quot;&gt;Google AI Studio&lt;/a&gt; -- no credit card required. Hit &quot;Create API key&quot; in the top right, or &quot;Get API key&quot; in the left sidebar. The free tier is generous enough for development. If you go this route, use the &lt;code&gt;Umbraco.AI.Google&lt;/code&gt; provider and configure the connection in the backoffice accordingly.&lt;/p&gt;&#xA;&#xA;&#xA;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  Step 7: Run and verify&#xA;&lt;/h2&gt;&#xA;&#xA;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight shell&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;src/AI.Woowoo.TestSite&#xA;dotnet run&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;Once it&#x27;s running, log in (&lt;code&gt;admin@example.com&lt;/code&gt; / &lt;code&gt;1234567890&lt;/code&gt;) and navigate to the &lt;strong&gt;Umbraco.AI&lt;/strong&gt; section in the backoffice. You should see:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;A seeded OpenAI connection&lt;/li&gt;&#xA;&lt;li&gt;A profile&lt;/li&gt;&#xA;&lt;li&gt;A context&lt;/li&gt;&#xA;&lt;li&gt;Several prompts&lt;/li&gt;&#xA;&lt;li&gt;Several agents&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;If you added a real API key, try running a prompt or agent to confirm the connection is live.&lt;/p&gt;&#xA;&#xA;&#xA;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  Step 8: Make the initial commit&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Before staging everything, do a quick sanity check: open &lt;code&gt;UmbracoAISeedData.cs&lt;/code&gt; and confirm there&#x27;s no real API key in there.&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight shell&quot;&gt;&lt;code&gt;git add &lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt;&#xA;git commit &lt;span class=&quot;nt&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;chore: initial scaffold from Lotte&#x27;s Opinionated Package Starter Template&quot;&lt;/span&gt;&#xA;git push &lt;span class=&quot;nt&quot;&gt;-u&lt;/span&gt; origin main&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;Prerequisite:&lt;/strong&gt; before pushing, go to GitHub and create a new empty repository named &lt;code&gt;Umbraco.Community.AI.Woowoo&lt;/code&gt; (skip the readme, license, and gitignore options -- the template already created those locally). The template already configured the remote, so &lt;code&gt;git push&lt;/code&gt; goes straight to the right place.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&#xA;&#xA;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  What&#x27;s next&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;The environment is now ready:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;code&gt;src/AI.Woowoo/&lt;/code&gt; -- the package project, clean and ready for package code&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;code&gt;src/AI.Woowoo.TestSite/&lt;/code&gt; -- a full Umbraco 17 &#x2B; Umbraco.AI host to develop and test against, with demo data seeded&lt;/li&gt;&#xA;&lt;li&gt;GitHub Actions configured for NuGet publishing on version tags&lt;/li&gt;&#xA;&lt;li&gt;All five AI providers installed and ready to configure&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;When it comes to implementing the package itself, the first thing to add to &lt;code&gt;src/AI.Woowoo/AI.Woowoo.csproj&lt;/code&gt; is a reference to &lt;code&gt;Umbraco.AI.Core&lt;/code&gt; -- the package that contains all the extension points (custom tools, middleware, guardrail evaluators, etc.):&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight shell&quot;&gt;&lt;code&gt;dotnet add src/AI.Woowoo package Umbraco.AI.Core &lt;span class=&quot;nt&quot;&gt;--version&lt;/span&gt; 1.6.0&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;Note that &lt;code&gt;Umbraco.AI.Core&lt;/code&gt; 1.6.0 requires Umbraco.Cms 17.1.0 or higher. The template scaffolds the package project against 17.0.0, so bump the four Umbraco.Cms references in the same file to 17.1.0 when you add this.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The next step is implementing the &lt;code&gt;Umbraco.Community.AI.Woowoo&lt;/code&gt; package itself -- but that&#x27;s a story for another post.&lt;/p&gt;]]></description>
                    <pubDate>Thu, 19 Mar 2026 09:30:57 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/growcreate.schemagenerator</guid>
                    <title>Growcreate.SchemaGenerator</title>
                    <link>https://marketplace.umbraco.com/package/growcreate.schemagenerator</link>
                    <description><![CDATA[Schema Generator for Umbraco to create and render schema objects. Map document type properties to schema properties and allow editors to populate additional schemas.]]></description>
                    <pubDate>Thu, 19 Mar 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.ai.propertyvalidation</guid>
                    <title>Umbraco.Community.AI.PropertyValidation</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.ai.propertyvalidation</link>
                    <description><![CDATA[AI-powered property validation for Umbraco CMS using the Umbraco.AI infrastructure.]]></description>
                    <pubDate>Thu, 19 Mar 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/kraftvaerk.umbraco.alchemy</guid>
                    <title>Kraftvaerk.Umbraco.Alchemy</title>
                    <link>https://marketplace.umbraco.com/package/kraftvaerk.umbraco.alchemy</link>
                    <description><![CDATA[AI-powered developer assistant for the Umbraco backoffice &#x2014; generates property descriptions, document type descriptions, UFM block labels, and content type icons.]]></description>
                    <pubDate>Thu, 19 Mar 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/oc.powersort</guid>
                    <title>OC.PowerSort</title>
                    <link>https://marketplace.umbraco.com/package/oc.powersort</link>
                    <description><![CDATA[A powerful sorting extension for Umbraco CMS that provides enhanced sorting capabilities for content nodes in the backoffice.]]></description>
                    <pubDate>Wed, 18 Mar 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://owain.codes/blog/2026/march/ocpowersort-package/</guid>
                    <title>OC.PowerSort package</title>
                    <link>https://owain.codes/blog/2026/march/ocpowersort-package/</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Wed, 18 Mar 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://umbracocommunity.social/@umbracoa11y/116246055536313833</guid>
                    <title>The Call for Speakers for UMBRAAD 2026 is open!</title>
                    <link>https://umbracocommunity.social/@umbracoa11y/116246055536313833</link>
                    <description><![CDATA[&#x1F680; The Call for Speakers for UMBRAAD 2026 is open! Take to the virtual stage and present your insights on digital accessibility to the Umbraco community during Global Accessibility Awareness Day. Whether you&#x27;re an experienced presenter or simply passionate about enhancing the web, your contribution is welcome! Key Details:&#x1F5D3;&#xFE0F;  Date: 21st May 2026&#x1F4A1;  Topics: Neurodiversity,  AI &amp; Accessibility, Inclusive UX, Accessibility Fatigue, and more!Submit your session idea: https://sessionize.com/umbraad-2026/]]></description>
                    <pubDate>Tue, 17 Mar 2026 19:27:22 Z</pubDate>
                        <category>community</category>
                        <category>mastodon</category>
                        <category>social</category>
                </item>
                <item>
                    <guid>https://www.nevitech.co.uk/blog/getting-started-with-umbraco-ai/</guid>
                    <title>Getting Started with Umbraco AI</title>
                    <link>https://www.nevitech.co.uk/blog/getting-started-with-umbraco-ai/</link>
                    <description><![CDATA[At last night&#x27;s Umbraco Kent Meetup, I gave a live demo on the new AI integrations in the Umbraco back office. If you missed it - or just want a recap - I&#x27;ve put together a blog post covering everything.&#xA;&#xA;www.nevitech.co.uk/blog/getting...&#xA;&#xA;#umbraco #ai #umbracoai @umb.fyi&#xA;&#xA;]]></description>
                    <pubDate>Tue, 17 Mar 2026 11:56:09 Z</pubDate>
                        <category>blog</category>
                        <category>community</category>
                </item>
                <item>
                    <guid>https://umbraco.com/blog/umbraco-s-spring-2026-g2-highlights-strong-usability-wins-across-headless-dxp-cms-and-webops/</guid>
                    <title>Umbraco Recognized as a G2 Leader Across CMS and Headless in the Spring 2026 Reports</title>
                    <link>https://umbraco.com/blog/umbraco-s-spring-2026-g2-highlights-strong-usability-wins-across-headless-dxp-cms-and-webops/</link>
                    <description><![CDATA[See Umbraco&#x2019;s Winter 2026 G2 results across CMS, Headless, DXP, and WebOps, including key badges, usability gains, and implementation highlights.]]></description>
                    <pubDate>Tue, 17 Mar 2026 00:00:00 Z</pubDate>
                        <category>hq</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.jobsjobsjobs</guid>
                    <title>Umbraco.Community.JobsJobsJobs</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.jobsjobsjobs</link>
                    <description><![CDATA[Backoffice dashboard for recurring Umbraco background jobs with status, manual triggering, persisted run history, cooperative stop support, and opt-in CRON scheduling.]]></description>
                    <pubDate>Tue, 17 Mar 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/oc.ufmfallbacks</guid>
                    <title>OC.UFMFallbacks</title>
                    <link>https://marketplace.umbraco.com/package/oc.ufmfallbacks</link>
                    <description><![CDATA[An Umbraco package that extends Umbraco Flavored Markdown (UFM) with a {fbk:} component, giving you property fallbacks and text filters directly inside block labels and other UFM contexts.]]></description>
                    <pubDate>Tue, 17 Mar 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://owain.codes/blog/2026/march/ocufmfallbacks-package/</guid>
                    <title>OC.UFMFallbacks Package</title>
                    <link>https://owain.codes/blog/2026/march/ocufmfallbacks-package/</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Tue, 17 Mar 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://www.youtube.com/watch?v=Vn881L24YZU</guid>
                    <title>The Umbraco Playground &#x2014; Experiment, build, and share 1</title>
                    <link>https://www.youtube.com/watch?v=Vn881L24YZU</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Mon, 16 Mar 2026 10:04:35 Z</pubDate>
                        <category>community</category>
                        <category>youtube</category>
                </item>
                <item>
                    <guid>https://richardsoeteman.net/blog/automatically-filter-content-delivery-api-content/</guid>
                    <title>Automatically Filter Content Delivery API Content</title>
                    <link>https://richardsoeteman.net/blog/automatically-filter-content-delivery-api-content/</link>
                    <description><![CDATA[Just Blogged:&#xA;Automatically Filter Content Delivery API Content without applying a filter in querystring parameters..&#xA;https://richardsoeteman.net/blog/automatically-filter-content-delivery-api-content/]]></description>
                    <pubDate>Mon, 16 Mar 2026 09:37:18 Z</pubDate>
                        <category>blog</category>
                        <category>community</category>
                </item>
                <item>
                    <guid>https://dev.to/matthewwise/a-practical-guide-to-svgs-in-umbraco-1gm6</guid>
                    <title>A Practical Guide to SVGs in Umbraco</title>
                    <link>https://dev.to/matthewwise/a-practical-guide-to-svgs-in-umbraco-1gm6</link>
                    <description><![CDATA[&lt;p&gt;If you&#x27;ve ever tried to use SVGs properly in Umbraco, you&#x27;ll know it&#x27;s not quite plug-and-play. Icons, logos, illustrations - SVGs are everywhere on the modern web.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Out of the box Umbraco will let you upload SVGs. It even has a dedicated &lt;code&gt;Vector Graphics (SVG)&lt;/code&gt; media type. But there are two things I wanted to improve.&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  The Two Problems&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;Inlining for CSS control.&lt;/strong&gt; &lt;/p&gt;&#xA;&#xA;&lt;p&gt;If you serve an SVG as an &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; tag, it works - but you lose most of what makes SVGs useful. You can&#x27;t style it with CSS, you can&#x27;t use &lt;code&gt;currentColor&lt;/code&gt; to inherit text colour, you can&#x27;t target individual paths for hover states or animations. To get that level of control you need the SVG markup inlined directly into your HTML.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;But inlining creates its own issues. An &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; tag sandboxes its content - scripts inside the SVG won&#x27;t execute. Inline that same SVG into the page and any &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tags or &lt;code&gt;javascript:&lt;/code&gt; handlers will run. An editor could unknowingly upload an SVG containing an XSS attack, and you&#x27;d be serving it straight into the DOM. SVGs from design tools also come with hard-coded &lt;code&gt;width&lt;/code&gt; and &lt;code&gt;height&lt;/code&gt; attributes that fight your CSS when inlined - you want a &lt;code&gt;viewBox&lt;/code&gt; instead.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;Duplicate requests on &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; tags.&lt;/strong&gt; &lt;br&gt;&#xA;Not every SVG needs to be inlined. But when you call &lt;code&gt;GetCropUrl()&lt;/code&gt; on a media item, Umbraco adds crop and resize parameters to the URL. So &lt;code&gt;GetCropUrl(200)&lt;/code&gt; produces &lt;code&gt;example.svg?width=200&lt;/code&gt;, and &lt;code&gt;GetCropUrl(48)&lt;/code&gt; produces &lt;code&gt;example.svg?width=48&lt;/code&gt;. The browser treats those as different URLs - meaning if you use the same SVG at multiple sizes, it gets downloaded multiple times instead of once. For a vector image that scales to any size, those parameters are pointless and the duplicate requests are pure waste.&lt;/p&gt;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  Securing SVG Uploads&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Since we&#x27;re inlining SVGs into the page, we need to make sure they&#x27;re safe before they get anywhere near the DOM.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Umbraco has an &lt;a href=&quot;https://docs.umbraco.com/umbraco-cms/reference/security/server-side-file-validation#ifilestreamsecurityanalyzer&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;code&gt;IFileStreamSecurityAnalyzer&lt;/code&gt;&lt;/a&gt; interface that gets called when media is uploaded. Umbraco doesn&#x27;t ship with an SVG implementation, but the docs include an example. My version makes two changes to that example: it drops the &lt;code&gt;xmlns&lt;/code&gt; check (since not all SVGs include it) and adds a check for &lt;code&gt;javascript:&lt;/code&gt; protocol handlers:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight csharp&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;internal&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SvgXssSecurityAnalyzer&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IFileStreamSecurityAnalyzer&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ShouldHandle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Stream&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fileStream&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;        &lt;span class=&quot;c1&quot;&gt;// reduce memory footprint by partially reading the file&lt;/span&gt;&#xA;        &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;startBuffer&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;256&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;&#xA;        &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;endBuffer&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;256&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;&#xA;        &lt;span class=&quot;n&quot;&gt;fileStream&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ReadExactly&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;startBuffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&#xA;        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endBuffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Length&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fileStream&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&#xA;            &lt;span class=&quot;n&quot;&gt;fileStream&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Seek&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SeekOrigin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Begin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&#xA;        &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&#xA;            &lt;span class=&quot;n&quot;&gt;fileStream&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Seek&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fileStream&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Length&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;endBuffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SeekOrigin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Begin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&#xA;        &lt;span class=&quot;n&quot;&gt;fileStream&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ReadExactly&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endBuffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&#xA;        &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;startString&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Encoding&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UTF8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;startBuffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&#xA;        &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;endString&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Encoding&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UTF8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endBuffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&#xA;        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;startString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Contains&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&amp;lt;svg&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&#xA;               &lt;span class=&quot;p&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;endString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Contains&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/svg&amp;gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&#xA;    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;IsConsideredSafe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Stream&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fileStream&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;        &lt;span class=&quot;c1&quot;&gt;// do not use a using as this will dispose of the underlying stream&lt;/span&gt;&#xA;        &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;streamReader&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;StreamReader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fileStream&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&#xA;        &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fileContent&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;streamReader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ReadToEnd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;&#xA;        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fileContent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Contains&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&amp;lt;script&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&#xA;                &lt;span class=&quot;p&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fileContent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Contains&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/script&amp;gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&#xA;                &lt;span class=&quot;p&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fileContent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Contains&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;javascript:&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;Registration is a single line in DI:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight csharp&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;services&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AddSingleton&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IFileStreamSecurityAnalyzer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SvgXssSecurityAnalyzer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;();&lt;/span&gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  Storing SVG Content for Inline Rendering&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;To inline SVGs in your templates, you need the actual SVG markup available at render time. You could read the file on every request, but that&#x27;s expensive. Storing the markup as a property on the media item means it gets served from Umbraco&#x27;s cache instead of hitting IO on every render.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Add a custom property called &lt;code&gt;svgContent&lt;/code&gt; to the &lt;code&gt;Vector Graphics (SVG)&lt;/code&gt; media type in Umbraco, then create a notification handler that populates it automatically whenever an SVG is saved.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The property type matters here. A &lt;code&gt;Label (string)&lt;/code&gt; won&#x27;t work - SVG markup easily exceeds 512 characters. If you&#x27;re on Umbraco 17.3.0&#x2B; the &lt;code&gt;Label (long string)&lt;/code&gt; type stores as &lt;code&gt;Text&lt;/code&gt; in the database, but on earlier 17.x versions there&#x27;s a &lt;a href=&quot;https://github.com/umbraco/Umbraco-CMS/issues/21853&quot; rel=&quot;noopener noreferrer&quot;&gt;known issue&lt;/a&gt; where it&#x27;s capped at 512 characters. If that affects you, you&#x27;ll need a custom data type to store the content.&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight typescript&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;//Umbraco extension manifest:&lt;/span&gt;&#xA;&lt;span class=&quot;k&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;manifests&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;UmbExtensionManifest&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;        &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;propertyEditorUi&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&#xA;        &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;alias&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Website.PropertyEditorUi.LongLabel&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&#xA;        &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Website Long label&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&#xA;        &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;elementName&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;umb-property-editor-ui-label&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&#xA;        &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;meta&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;            &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;label&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Long Label&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&#xA;            &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;icon&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;icon-list&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&#xA;            &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;group&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;common&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&#xA;            &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;propertyEditorSchemaAlias&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Umbraco.Plain.Json&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//Means we get IHtmlEncodedString in c#&lt;/span&gt;&#xA;        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;Using a &lt;code&gt;MediaSavingNotification&lt;/code&gt; handler to read the file content, clean up the markup, and stores it in &lt;code&gt;svgContent&lt;/code&gt; whenever an SVG is saved. For each SVG node it generates a &lt;code&gt;viewBox&lt;/code&gt; from existing dimensions if one doesn&#x27;t exist, strips &lt;code&gt;width&lt;/code&gt; and &lt;code&gt;height&lt;/code&gt; attributes, and removes the &lt;code&gt;xmlns&lt;/code&gt; declaration. The &lt;code&gt;viewBox&lt;/code&gt; logic here is based on the approach used in &lt;a href=&quot;https://github.com/umbraco-community/Our-Umbraco-TagHelpers&quot; rel=&quot;noopener noreferrer&quot;&gt;Our.Umbraco.TagHelpers&lt;/a&gt; - well worth a look if you haven&#x27;t already:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight csharp&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;HtmlDocument&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;doc&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;HtmlDocument&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;&#xA;&lt;span class=&quot;n&quot;&gt;doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;LoadHtml&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fileContents&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&#xA;&lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;svgs&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DocumentNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SelectNodes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;//svg&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&#xA;&#xA;&lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;svgNode&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;svgs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;svgNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Attributes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Contains&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;width&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&#xA;        &lt;span class=&quot;p&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;svgNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Attributes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Contains&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;height&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;svgNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Attributes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Contains&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;viewbox&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&#xA;        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Decimal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;TryParse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&#xA;                &lt;span class=&quot;n&quot;&gt;svgNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetAttributeValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;width&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;0&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;&#xA;                &lt;span class=&quot;k&quot;&gt;out&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;width&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&#xA;            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Decimal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;TryParse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&#xA;                &lt;span class=&quot;n&quot;&gt;svgNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetAttributeValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;height&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;0&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;&#xA;                &lt;span class=&quot;k&quot;&gt;out&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;height&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&#xA;            &lt;span class=&quot;n&quot;&gt;svgNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SetAttributeValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;viewbox&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&#xA;                &lt;span class=&quot;s&quot;&gt;$&quot;0 0 &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&#xA;        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&#xA;        &lt;span class=&quot;n&quot;&gt;svgNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Attributes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Remove&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;width&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&#xA;        &lt;span class=&quot;n&quot;&gt;svgNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Attributes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Remove&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;height&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&#xA;    &lt;span class=&quot;n&quot;&gt;svgNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Attributes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Remove&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;xmlns&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;This all happens once at upload time. Editors don&#x27;t need to think about it. The full handler with error handling is in the complete example at the end of the post.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The handler is registered on the Umbraco builder:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight csharp&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AddNotificationAsyncHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MediaSavingNotification&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;StoreSvgContentMediaSavingNotificationHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;();&lt;/span&gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  Cleaning Up the Image Pipeline for SVGs&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Remember that issue with adding width and height to SVG output. here&#x27;s how to fix that&lt;/p&gt;&#xA;&#xA;&lt;p&gt;what about something along this line?&lt;br&gt;&#xA;The &lt;code&gt;DontCropSvgsImageUrlGenerator&lt;/code&gt; wraps the default generator. If the image is an SVG, it creates a new &lt;code&gt;ImageUrlGenerationOptions&lt;/code&gt; with only the URL - stripping all crop and resize parameters. Everything else passes through normally:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight csharp&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetImageUrl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ImageUrlGenerationOptions&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ImageUrl&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&#xA;    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ImageUrl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;EndsWith&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;.svg&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_imageGenerator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetImageUrl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&#xA;            &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ImageUrlGenerationOptions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ImageUrl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&#xA;    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_imageGenerator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetImageUrl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;The registration replaces Umbraco&#x27;s default &lt;code&gt;IImageUrlGenerator&lt;/code&gt;, wrapping the original &lt;code&gt;ImageSharpImageUrlGenerator&lt;/code&gt; inside the decorator:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight csharp&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;services&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RemoveAll&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IImageUrlGenerator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;();&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//Umbraco only has one by default&lt;/span&gt;&#xA;&lt;span class=&quot;n&quot;&gt;services&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AddSingleton&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IImageUrlGenerator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DontCropSvgsImageUrlGenerator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;(&lt;/span&gt;&#xA;    &lt;span class=&quot;n&quot;&gt;sp&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;        &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;generator&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ImageSharpImageUrlGenerator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&#xA;            &lt;span class=&quot;n&quot;&gt;sp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetRequiredService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SixLabors&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ImageSharp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Configuration&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;(),&lt;/span&gt;&#xA;            &lt;span class=&quot;n&quot;&gt;sp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RequestAuthorizationUtilities&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;(),&lt;/span&gt;&#xA;            &lt;span class=&quot;n&quot;&gt;sp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetRequiredService&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IOptions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ImageSharpMiddlewareOptions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&amp;gt;());&lt;/span&gt;&#xA;        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;DontCropSvgsImageUrlGenerator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;generator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  Rendering the SVG Content&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;With all of this in place, using SVGs in Razor views is straightforward. An extension method on &lt;code&gt;MediaWithCrops&lt;/code&gt; surfaces the stored SVG content (using the &lt;a href=&quot;https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-14#extension-members&quot; rel=&quot;noopener noreferrer&quot;&gt;C# 14 extension members&lt;/a&gt; syntax on .NET 10):&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight csharp&quot;&gt;&lt;code&gt;&lt;span class=&quot;nf&quot;&gt;extension&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MediaWithCrops&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;media&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IHtmlEncodedString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SvgContent&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt;&#xA;        &lt;span class=&quot;n&quot;&gt;media&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Content&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;UmbracoMediaVectorGraphics&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;svg&lt;/span&gt;&#xA;            &lt;span class=&quot;p&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;svg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SvgContent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;IsNullOrWhiteSpace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&#xA;            &lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;svg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SvgContent&lt;/span&gt;&#xA;            &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;Then in a component, render the SVG inline if available, falling back to an &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; tag otherwise:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight html&quot;&gt;&lt;code&gt;@if (Model.Icon.SvgContent is not null)&#xA;{&#xA;    @Model.Icon.SvgContent&#xA;}&#xA;else&#xA;{&#xA;    &lt;span class=&quot;nt&quot;&gt;&amp;lt;img&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;src=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;@Model.Icon.GetCropUrl(48, 48)&quot;&lt;/span&gt;&#xA;         &lt;span class=&quot;na&quot;&gt;alt=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;@Model.Icon.GetAltText()&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;loading=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;lazy&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;An alternative here would be to create a custom tag helper in a similar way to Our.Umbraco.TagHelpers.&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  Wrapping Up&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Together it gives you a solid SVG story in Umbraco: editors upload SVGs as normal, the code secures them, fixes the sizing, and serves them from a single URL or inline with full CSS control as the developer and site need.&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  The Full Handler&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Here&#x27;s the complete &lt;code&gt;StoreSvgContentMediaSavingNotificationHandler&lt;/code&gt; ready to copy-paste:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight csharp&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;internal&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;StoreSvgContentMediaSavingNotificationHandler&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;INotificationAsyncHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MediaSavingNotification&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SvgContentPropertyAlias&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;svgContent&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&#xA;&#xA;    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MediaFileManager&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_mediaFileManager&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&#xA;    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ILogger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;StoreSvgContentMediaSavingNotificationHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_logger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&#xA;&#xA;    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;StoreSvgContentMediaSavingNotificationHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&#xA;        &lt;span class=&quot;n&quot;&gt;MediaFileManager&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mediaFileManager&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&#xA;        &lt;span class=&quot;n&quot;&gt;ILogger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;StoreSvgContentMediaSavingNotificationHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;        &lt;span class=&quot;n&quot;&gt;_mediaFileManager&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mediaFileManager&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&#xA;        &lt;span class=&quot;n&quot;&gt;_logger&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&#xA;    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Task&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;HandleAsync&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&#xA;        &lt;span class=&quot;n&quot;&gt;MediaSavingNotification&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;notification&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&#xA;        &lt;span class=&quot;n&quot;&gt;CancellationToken&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cancellationToken&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;        &lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;svg&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;notification&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SavedEntities&lt;/span&gt;&#xA;            &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Where&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ContentType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Alias&lt;/span&gt;&#xA;                &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;InvariantEquals&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UmbConstants&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Conventions&lt;/span&gt;&#xA;                    &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MediaTypes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;VectorGraphicsAlias&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;&#xA;        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;svg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;HasProperty&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SvgContentPropertyAlias&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;continue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&#xA;            &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&#xA;            &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;                &lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;content&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_mediaFileManager&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetFile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;svg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;out&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&#xA;                &lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reader&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;StreamReader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&#xA;                &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fileContents&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&#xA;                    &lt;span class=&quot;k&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ReadToEndAsync&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cancellationToken&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&#xA;&#xA;                &lt;span class=&quot;n&quot;&gt;HtmlDocument&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;doc&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;HtmlDocument&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;&#xA;                &lt;span class=&quot;n&quot;&gt;doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;LoadHtml&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fileContents&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&#xA;                &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;svgs&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DocumentNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SelectNodes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;//svg&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&#xA;&#xA;                &lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;svgNode&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;svgs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&#xA;                &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;                    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;svgNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Attributes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Contains&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;width&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&#xA;                        &lt;span class=&quot;p&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;svgNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Attributes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Contains&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;height&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&#xA;                    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;                        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;svgNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Attributes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Contains&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;viewbox&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&#xA;                        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;                            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Decimal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;TryParse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&#xA;                                &lt;span class=&quot;n&quot;&gt;svgNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetAttributeValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;width&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;0&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;&#xA;                                &lt;span class=&quot;k&quot;&gt;out&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;width&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&#xA;                            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Decimal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;TryParse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&#xA;                                &lt;span class=&quot;n&quot;&gt;svgNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetAttributeValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;height&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;0&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;&#xA;                                &lt;span class=&quot;k&quot;&gt;out&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;height&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&#xA;                            &lt;span class=&quot;n&quot;&gt;svgNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SetAttributeValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;viewbox&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&#xA;                                &lt;span class=&quot;s&quot;&gt;$&quot;0 0 &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&#xA;                        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&#xA;                        &lt;span class=&quot;n&quot;&gt;svgNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Attributes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Remove&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;width&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&#xA;                        &lt;span class=&quot;n&quot;&gt;svgNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Attributes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Remove&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;height&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&#xA;                    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&#xA;                    &lt;span class=&quot;n&quot;&gt;svgNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Attributes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Remove&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;xmlns&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&#xA;                &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&#xA;                &lt;span class=&quot;n&quot;&gt;fileContents&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DocumentNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;OuterHtml&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&#xA;                &lt;span class=&quot;n&quot;&gt;svg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SetValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SvgContentPropertyAlias&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fileContents&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&#xA;            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;            &lt;span class=&quot;k&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Exception&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ex&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IOException&lt;/span&gt;&#xA;                &lt;span class=&quot;p&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ex&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FileNotFoundException&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&#xA;            &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;                &lt;span class=&quot;n&quot;&gt;_logger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;LogError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&#xA;                    &lt;span class=&quot;s&quot;&gt;&quot;Unable to read file to set SVG content &quot;&lt;/span&gt;&#xA;                    &lt;span class=&quot;p&quot;&gt;&#x2B;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;for media item with ID {MediaId}.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&#xA;                    &lt;span class=&quot;n&quot;&gt;svg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&#xA;            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  References&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&quot;https://docs.umbraco.com/umbraco-cms/reference/security/server-side-file-validation#ifilestreamsecurityanalyzer&quot; rel=&quot;noopener noreferrer&quot;&gt;Server-side file validation | Umbraco Documentation&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&quot;https://github.com/umbraco-community/Our-Umbraco-TagHelpers&quot; rel=&quot;noopener noreferrer&quot;&gt;Our.Umbraco.TagHelpers&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;]]></description>
                    <pubDate>Mon, 16 Mar 2026 09:22:37 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/oc.ufmmemberlookup</guid>
                    <title>OC.UFMMemberLookup</title>
                    <link>https://marketplace.umbraco.com/package/oc.ufmmemberlookup</link>
                    <description><![CDATA[An Umbraco Flavoured Markdown extension to allow for searching Member data]]></description>
                    <pubDate>Mon, 16 Mar 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.urestore</guid>
                    <title>Umbraco.Community.uRestore</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.urestore</link>
                    <description><![CDATA[Extends the Umbraco backoffice with a Property Restore workspace tab, allowing editors to compare any saved content version against the current draft and selectively restore individual property values without affecting the rest of the content.]]></description>
                    <pubDate>Mon, 16 Mar 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://umbraco.com/blog/the-agent-ready-cms-introducing-agent-skills-umbraco-backoffice-extension/</guid>
                    <title>The Agent-Ready CMS:  Introducing Agent Skills: Umbraco Backoffice Extension</title>
                    <link>https://umbraco.com/blog/the-agent-ready-cms-introducing-agent-skills-umbraco-backoffice-extension/</link>
                    <description><![CDATA[From turning rough ideas into working wireframes to building complex backoffice extensions without hallucinations, discover how we&#x2019;re making AI a practical tool for Umbraco development.]]></description>
                    <pubDate>Mon, 16 Mar 2026 00:00:00 Z</pubDate>
                        <category>hq</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/pulseforumbraco</guid>
                    <title>PulseForUmbraco</title>
                    <link>https://marketplace.umbraco.com/package/pulseforumbraco</link>
                    <description><![CDATA[Your Umbraco site&#x27;s operational health monitor. Pulse scans your content, configuration, performance, and security &#x2014; giving you an actionable health score and one-click remediation from inside the backoffice.]]></description>
                    <pubDate>Mon, 16 Mar 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://cornehoskam.com/posts/why-implicit-scoring-isnt-always-enough-for-personalization/</guid>
                    <title>Why Implicit Scoring Isn&#x27;t Always Enough for Personalization</title>
                    <link>https://cornehoskam.com/posts/why-implicit-scoring-isnt-always-enough-for-personalization/</link>
                    <description><![CDATA[Implicit scoring works great for most visitors, but what happens when the system gets it wrong? Let&#x27;s take a look at how Explicit Scoring in Umbraco Engage gives marketers the confidence to stop guessing.]]></description>
                    <pubDate>Mon, 16 Mar 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://owain.codes/blog/2026/march/ocufmmemberslookup-package/</guid>
                    <title>OC.UFMMembersLookup package</title>
                    <link>https://owain.codes/blog/2026/march/ocufmmemberslookup-package/</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Mon, 16 Mar 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://owain.codes/blog/2026/march/ocufmmemberlookup-package/</guid>
                    <title>OC.UFMMemberLookup Package</title>
                    <link>https://owain.codes/blog/2026/march/ocufmmemberlookup-package/</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Mon, 16 Mar 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://github.com/limbo-works/Limbo.Umbraco.Separator/releases/tag/v17.0.0</guid>
                    <title>Limbo.Umbraco.Separator 17.0.0</title>
                    <link>https://github.com/limbo-works/Limbo.Umbraco.Separator/releases/tag/v17.0.0</link>
                    <description><![CDATA[Limbo.Separator is a small package for Umbraco that adds a property editor serving as a separator to give a better overview of properties within your Umbraco content types.]]></description>
                    <pubDate>Sun, 15 Mar 2026 20:58:37 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                </item>
                <item>
                    <guid>https://www.enkelmedia.se/blogg/2026/3/15/programmatically-create-umbraco-members-and-set-password?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=rss</guid>
                    <title>Programmatically create Umbraco Members and set Password</title>
                    <link>https://www.enkelmedia.se/blogg/2026/3/15/programmatically-create-umbraco-members-and-set-password?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=rss</link>
                    <description><![CDATA[&lt;p&gt;Over the last months, I&#x27;ve been working on moving websites from Umbraco 13 up to Umbraco 17. I had a really hard time to find good documentation on how to work with Members so I figured I&#x27;ll write a short blog post to fill some of the &quot;gaps&quot; I experienced in the documentation.&lt;/p&gt;&#xA;&lt;h2&gt;What is Member in Umbraco?&lt;/h2&gt;&#xA;&lt;p&gt;A &lt;strong&gt;Member&lt;/strong&gt; in Umbraco is an external or frontend user. In other words, this is the kind of account you would use for things like a customer area, intranet login, gated content, forums, and similar functionality on the public-facing site.&lt;/p&gt;&#xA;&lt;h2&gt;Working with Members programmatically&lt;/h2&gt;&#xA;&lt;p&gt;When working with Umbraco Members programmatically you need to familiarize your self with the &lt;em&gt;IMemberService &lt;/em&gt;and the &lt;em&gt;IMemberManager&lt;/em&gt;.&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;IMemberService is used to work with the IMember object, set username, email and update custom properties.&lt;/li&gt;&#xA;&lt;li&gt;IMemberManager is used to perform login, get current member and set password.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Here is a code sample that will create a member programmatically and set the password programmatically.&lt;/p&gt;&#xA;&lt;div&gt;&#xA;&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;public class MemberRegistrationService&#xA;{&#xA;    private readonly IMemberService _memberService;&#xA;    private readonly IMemberManager _memberManager;&#xA;    private readonly IPasswordHasher _passwordHasher;&#xA;&#xA;    public MemberRegistrationService(&#xA;        IMemberService memberService,&#xA;        IMemberManager memberManager,&#xA;        IPasswordHasher passwordHasher&#xA;        )&#xA;    {&#xA;        _memberService = memberService;&#xA;        _memberManager = memberManager;&#xA;        _passwordHasher = passwordHasher;&#xA;    }&#xA;&#xA;    public async Task&amp;lt;IMember&amp;gt; CreateMemberAsync(string email, string password, string name)&#xA;    {&#xA;        var member = _memberService.CreateMember(&#xA;            email,&#xA;            email,&#xA;            name,&#xA;            &amp;quot;Member&amp;quot;); // or Member.ModelTypeAlias with ModelsBuilder&#xA;        &#xA;        member.IsApproved = true;&#xA;&#xA;        _memberService.Save(member);&#xA;&#xA;        // Optionally add to a role&#xA;        _memberService.AssignRole(member.Id, &amp;quot;Member&amp;quot;); &#xA;&#xA;        // Set password&#xA;        var memberIdentity = await _memberManager.FindByIdAsync(member.Id.ToString());&#xA;        var passwordResult = await _memberManager.AddPasswordAsync(memberIdentity!, password);&#xA;&#xA;        // Alternative way of setting password&#xA;        member.RawPasswordValue = _passwordHasher.HashPassword(password);&#xA;&#xA;        return member;&#xA;    }&#xA;}&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&lt;p&gt;&#xA0;&lt;/p&gt;&#xA;&lt;p&gt;..&lt;/p&gt;&#xA;&lt;p&gt;&#xA0;&lt;/p&gt;&#xA;&lt;p&gt;&#xA0;&lt;/p&gt;]]></description>
                    <pubDate>Sun, 15 Mar 2026 14:19:20 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://dev.to/d_inventor/im-learning-python-with-ai-and-tdd-40aa</guid>
                    <title>I&#x27;m learning python with AI and TDD</title>
                    <link>https://dev.to/d_inventor/im-learning-python-with-ai-and-tdd-40aa</link>
                    <description><![CDATA[&lt;p&gt;I decided to make my next hobby project in python. I used this project to learn python, but also to become familiar with AI-assisted coding. In this article I document my experiences with AI as a pair programming buddy, doing Test-Driven Development together.&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  About TDD, the project and me&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Test-Driven Development is about writing tests before writing your code. This is often done in the Red, Green, Refactor cycle: Write a failing test, specifying the behaviour that the code should exhibit, make all tests pass with as few changes as possible and finally make your code (and your tests) nice. It&#x27;s a design tool that helps make your code easier to understand and maintain.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The project is a self-hosted information database that connects &lt;a href=&quot;https://animalcrossing.nintendo.com/amiibo/#welcome&quot; rel=&quot;noopener noreferrer&quot;&gt;Animal Crossing Amiibos&lt;/a&gt; to information on &lt;a href=&quot;https://nookipedia.com/wiki/Main_Page&quot; rel=&quot;noopener noreferrer&quot;&gt;Nookipedia&lt;/a&gt;. An API exposes the data so that an app can scan an amiibo and direct the user straight to the character&#x27;s page on the Nookipedia. The project, besides providing desired functionality, is also an excuse for me to try out some enterprise software patterns that I wish to learn more about.&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&lt;div class=&quot;ltag-github-readme-tag&quot;&gt;&#xA;  &lt;div class=&quot;readme-overview&quot;&gt;&#xA;    &lt;h2&gt;&#xA;      &lt;img src=&quot;https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg&quot; alt=&quot;GitHub logo&quot;&gt;&#xA;      &lt;a href=&quot;https://github.com/D-Inventor&quot; rel=&quot;noopener noreferrer&quot;&gt;&#xA;        D-Inventor&#xA;      &lt;/a&gt; / &lt;a href=&quot;https://github.com/D-Inventor/my-animal-crossing-app&quot; rel=&quot;noopener noreferrer&quot;&gt;&#xA;        my-animal-crossing-app&#xA;      &lt;/a&gt;&#xA;    &lt;/h2&gt;&#xA;    &lt;h3&gt;&#xA;      This is a hobby project. It is a combination of an app for android and a python-based server API. The server supplies information about Animal Crossing villagers. The app lets me scan Amiibo cards and then I can see basic information about the villager.&#xA;    &lt;/h3&gt;&#xA;  &lt;/div&gt;&#xA;  &lt;div class=&quot;ltag-github-body&quot;&gt;&#xA;    &#xA;&lt;div id=&quot;readme&quot; class=&quot;md&quot;&gt;&#xA;&lt;p&gt;This is a hobby project.&#xA;I wanted to get easy access to basic villager information from my Amiibo card collection.&lt;/p&gt;&#xA;&lt;p&gt;This project combines an android app with a python-based API so that I can scan the NFC chip of an amiibo card and then fetch the information. That&#x27;s all.&lt;/p&gt;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;/div&gt;&#xA;&lt;br&gt;&#xA;  &lt;div class=&quot;gh-btn-container&quot;&gt;&lt;a class=&quot;gh-btn&quot; href=&quot;https://github.com/D-Inventor/my-animal-crossing-app&quot; rel=&quot;noopener noreferrer&quot;&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;&#xA;&lt;br&gt;&#xA;&lt;/div&gt;&#xA;&lt;br&gt;&#xA;&#xA;&#xA;&lt;p&gt;I am a dotnet developer with very little python experience. Python has a special place in my heart, because it&#x27;s the first language that I earned some money with. That was more than 10 years ago and I haven&#x27;t touched python that much since then.&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  AI as a pair programming buddy&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Most of the code in this project has been written by AI. Overall, the results were mostly good, sometimes very frustrating, but sometimes also very impressive.&lt;/p&gt;&#xA;&#xA;&lt;h3&gt;&#xA;  &#xA;  &#xA;  Scaffolding a project baseline&#xA;&lt;/h3&gt;&#xA;&#xA;&lt;p&gt;Yes, AI got me started very quickly and effectively. I knew what I wanted: multiple python projects in a monorepo with some shared modules. I know what python code looks like, but actually setting up a project like this is quite a lot. Setting up testing with pytest, multiple independent modules with a shared pyproject.toml. Module imports are very confusing in python and if you don&#x27;t know what you&#x27;re doing, they&#x27;re difficult to get right sometimes. I asked the AI to do it for me with working examples of unit tests and shared modules. It did all of it, the code ran, the tests worked and the code looked acceptable. Big win &#x1F4AA;&lt;/p&gt;&#xA;&#xA;&lt;h3&gt;&#xA;  &#xA;  &#xA;  So many comments, so much &quot;documentation&quot;&#xA;&lt;/h3&gt;&#xA;&#xA;&lt;p&gt;It was really my own fault and it was quickly fixed. The AI was writing excessive comments. Every generated function filled with comments and &quot;documentation&quot;, detailing exactly what the code does. That&#x27;s not what I need comments for. I can read the code to see what it does. The thing here is that I let the AI generate its own instruction file and the instruction file literally instructed the AI to do this. I simply updated the instruction file and instructed the AI to never write comments.&lt;/p&gt;&#xA;&#xA;&lt;h3&gt;&#xA;  &#xA;  &#xA;  Stop! Wait! Not so fast! Not so much!&#xA;&lt;/h3&gt;&#xA;&#xA;&lt;p&gt;Some people may find it wonderful: just tell the AI what you want to make and it&#x27;ll happily build the whole thing for you. Or try to at least... Although it&#x27;s magnificent, I think it&#x27;s also incredibly irresponsible to let AI generate large amounts of code at once. Especially in a professional environment, I would be held personally responsible for bugs and mistakes and saying &quot;it&#x27;s the fault of the AI&quot; simply will not fly. It&#x27;s essential that I can review the code that the AI generates and I can only do this if I develop in small steps.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Test-Driven Development has been very helpful to put a leash on the AI. AI is very eager to write code and will simply sprint to the finish line if you let it. By strictly following the Red, Green, Refactor cycle, I was able to stay more in control of what the AI does and how it does it. It took a bit of trial-and-error, but the following instructions seemed to be very helpful:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Follow strict TDD practice with Red, Green and Refactor phases&lt;/li&gt;&#xA;&lt;li&gt;Always run the test in the Red phase to verify that the test fails in the way that we expect&lt;/li&gt;&#xA;&lt;li&gt;Prefer runtime failures over compile-time failures at all times&lt;/li&gt;&#xA;&lt;li&gt;Prefer failures on assertions over failures in code under test whenever this is reasonable&lt;/li&gt;&#xA;&lt;li&gt;Make sure in the green phase to write as little code as possible to make the test pass&lt;/li&gt;&#xA;&lt;li&gt;Always ask for verification from the user after each phase before proceeding to the next&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;Additionally, it seemed helpful when I start each session with &quot;We are pair programming buddies and we are going to do Test Driven Development&quot;. Nevertheless, the AI would still occasionally do more than I asked for, especially the green phase was difficult at times.&lt;/p&gt;&#xA;&#xA;&lt;h3&gt;&#xA;  &#xA;  &#xA;  Please give me an example in the form of an automated test&#xA;&lt;/h3&gt;&#xA;&#xA;&lt;p&gt;In this project I needed a handful of slightly more advanced concepts, including:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Messaging&lt;/li&gt;&#xA;&lt;li&gt;HTTP API calls&lt;/li&gt;&#xA;&lt;li&gt;Database querying&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;Though the concepts are familiar, I had never done them in python specifically. I know approximately what good integrations look like, but I simply needed some examples in python specifically. AI has been an excellent tool for learning and it helped me to understand python frameworks, tools and syntax. By asking about it in the shape of an automated test, I could also immediately apply the concepts I learned with Test Driven Development. This was a massive win! I would like to share a particular experience that really blew my mind.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I needed to build an integration with an external HTTP API. Coincidentally, I recently also had to do this for work in dotnet, so I had a good idea what a good integration looks like and also how a good unit test looks for such an integration. It had taken me about 5 hours to build in dotnet. I asked the AI to generate me an example of a unit test that demonstrates an http request and response in python. the unit test was quite bloated and unreadable, but it did work. I told the AI as much and I gave it an example of what I expected the test to look like, based on a test that I wrote in dotnet. I asked to refactor the test to make it as close as possible to the example that I gave. In just a few minutes it generated exactly the testing utility that I had spent several hours on earlier! This was shocking and incredibly impressive.&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  Thoughts overall&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;In general, I find the workflow decent. Although I did get much further with AI in a shorter amount of time than I would have without, I don&#x27;t believe (yet) that AI is a massive time-saver overall. That sounds like a contradiction, but you must see that it was my lack of understanding of the python ecosystem that held me back and not the speed by which I type code. Although the AI can create code much faster than me, the code is often not up to standards and at times I have had to throw away work of the past 10 minutes, because prompting for corrections was only making things worse.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;An important thing, in my opinion, is that AI may replace your typing, but shouldn&#x27;t replace your brain. The skills that I&#x27;ve developed as a professional developer are still required to judge the quality of the output and are still essential to prioritize long-term success over short-term gains.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;So yeah, if you haven&#x27;t tried it yet, perhaps you could also turn your AI into your TDD pair programming buddy. Thank you for reading and maybe I&#x27;ll see you in my next blog! &#x1F60A;&lt;/p&gt;]]></description>
                    <pubDate>Sun, 15 Mar 2026 08:57:27 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/digitalwonderlab.accessibilitytoolkit</guid>
                    <title>DigitalWonderlab.AccessibilityToolkit</title>
                    <link>https://marketplace.umbraco.com/package/digitalwonderlab.accessibilitytoolkit</link>
                    <description><![CDATA[Comprehensive WCAG 2.1 accessibility auditing for Umbraco backoffice. 37 checks across Level A, AA, and AAA with scored results, scan history, site-wide audits, printable reports, and CSV export. Lightweight with no external dependencies &#x2014; works on Umbraco Cloud and all hosting environments out of the box.]]></description>
                    <pubDate>Sat, 14 Mar 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.uaccessible</guid>
                    <title>Umbraco.Community.uAccessible</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.uaccessible</link>
                    <description><![CDATA[Accessibility audit reports for your Umbraco content pages, directly in the backoffice.]]></description>
                    <pubDate>Fri, 13 Mar 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://umbraco.com/blog/uprofile-march-2026-debasish-gracias/</guid>
                    <title>uProfile March 2026 - Debasish Gracias</title>
                    <link>https://umbraco.com/blog/uprofile-march-2026-debasish-gracias/</link>
                    <description><![CDATA[On a mission to inspire, connect, and bring together the global Umbraco community]]></description>
                    <pubDate>Fri, 13 Mar 2026 00:00:00 Z</pubDate>
                        <category>hq</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://dev.to/jemayn/a-first-look-at-load-balancing-the-umbraco-backoffice-1ihm</guid>
                    <title>A first look at load balancing the Umbraco backoffice</title>
                    <link>https://dev.to/jemayn/a-first-look-at-load-balancing-the-umbraco-backoffice-1ihm</link>
                    <description><![CDATA[&lt;p&gt;When Umbraco 17 released there was a lot of focus on it being the first LTS version of Umbraco using the new web component based backoffice, and for a lot of people that was important enough in itself.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;I must admit the only other feature I paid attention to is that dates now consistently have a timezone on them making it much easier to work with them.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;However, one thing I somehow managed to miss completely was that as of Umbraco 17 you can now load balance the backoffice of Umbraco.&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  Isn&#x27;t load balancing Umbraco an old feature?&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Load balancing Umbraco sites has been around for longer than I have used Umbraco - so at least since v7!&lt;/p&gt;&#xA;&#xA;&lt;p&gt;It used to work a certain way as shown in this diagram based on the official documentation:&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&quot;https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkahi3hzslz6mjahtzlen.png&quot; class=&quot;article-body-image-wrapper&quot;&gt;&lt;img src=&quot;https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkahi3hzslz6mjahtzlen.png&quot; alt=&quot;Traditional Umbraco load balancing architecture&quot; width=&quot;502&quot; height=&quot;719&quot;&gt;&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&quot;https://docs.umbraco.com/umbraco-cms/fundamentals/setup/server-setup/load-balancing#how-umbraco-load-balancing-works&quot; rel=&quot;noopener noreferrer&quot;&gt;Source: Umbraco documentation&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Which basically meant that what most people doing load balancing would do is spin up 2 Azure Web Apps, deploy the same code to both of them but have some settings that would designate one web app as the frontend app and one as the backend app.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Both apps would use the same database, and with some specific settings added you could allow the frontend app to scale out - for example by setting some rules that determines what amount of load the frontend should be under before it starts additional instances to automatically scale out.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;This works pretty well, but also means that the minimal amount of infrastructure was 2 web apps - and if you had a lot of editors then there was no way to scale out the backend to accommodate extra load there.&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  Load balancing the backoffice&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;So the new thing in Umbraco 17 is that you can now load balance everything. One immediate effect that could have is that you now just need a single web app for a basic scale out site, something like this:&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&quot;https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1o0plpamgcszwjnc54pn.png&quot; class=&quot;article-body-image-wrapper&quot;&gt;&lt;img src=&quot;https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1o0plpamgcszwjnc54pn.png&quot; alt=&quot;New Umbraco load balancing architecture&quot; width=&quot;742&quot; height=&quot;615&quot;&gt;&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&#xA;&lt;div class=&quot;crayons-card c-embed&quot;&gt;&#xA;&#xA;  &lt;br&gt;&#xA;Shout out &lt;a href=&quot;https://mermaid.js.org/&quot; rel=&quot;noopener noreferrer&quot;&gt;MermaidJS charts&lt;/a&gt;. AI agents are very good at translating described flows into charts, and it makes it so much easier to create visuals!&lt;br&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&lt;p&gt;This setup could theoretically make it cheaper, and it&#x27;s also easier to have a regular site running just 1 instance with the option of scaling out for big peaks in load without a bunch of extra setup! &lt;/p&gt;&#xA;&#xA;&lt;p&gt;So first you have to decide between the &quot;old&quot; way of load balancing with separate backend and frontend webapps and the &quot;new&quot; way of having a single scaleable app for both.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Secondly if choosing the &quot;new&quot; way of scaling a single app there is also a choice of whether the backoffice should use sticky sessions or be stateless.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;There are a lot of articles about pros and cons for both:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&quot;https://www.linode.com/docs/guides/configuring-load-balancer-sticky-session/&quot; rel=&quot;noopener noreferrer&quot;&gt;https://www.linode.com/docs/guides/configuring-load-balancer-sticky-session/&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&quot;https://www.imperva.com/learn/availability/sticky-session-persistence-and-cookies/&quot; rel=&quot;noopener noreferrer&quot;&gt;https://www.imperva.com/learn/availability/sticky-session-persistence-and-cookies/&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&quot;https://learn.microsoft.com/en-us/azure/load-balancer/load-balancer-best-practices#check-your-distribution-mode&quot; rel=&quot;noopener noreferrer&quot;&gt;https://learn.microsoft.com/en-us/azure/load-balancer/load-balancer-best-practices#check-your-distribution-mode&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;But in short the difference is how traffic is distributed:&lt;/p&gt;&#xA;&#xA;&lt;h3&gt;&#xA;  &#xA;  &#xA;  Sticky sessions&#xA;&lt;/h3&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Once a request hits the load balancer it is assigned to an instance and a cookie is returned on the response that has a reference to that instance. &lt;/li&gt;&#xA;&lt;li&gt;Future requests pass the cookie along to the load balancer, and it ensures that the new request hits the same instance.&lt;/li&gt;&#xA;&lt;li&gt;If x amount of users cause the server resources to spike to the point that more instances are added based on the load balancing rules, you can end up having a lot of users &quot;stick&quot; to the initial instance due to their cookies.&lt;/li&gt;&#xA;&lt;li&gt;If the instance a user is &quot;stuck&quot; to gets removed during a scale-down, the load balancer assigns them to a new instance - which can cause problems (more on that below).&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h3&gt;&#xA;  &#xA;  &#xA;  Stateless&#xA;&lt;/h3&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Once a request hits the load balancer it is assigned to the instance with the least load&lt;/li&gt;&#xA;&lt;li&gt;This ensures a much more equal distribution between instances&lt;/li&gt;&#xA;&lt;li&gt;This also makes things like sessions or SignalR connections a lot more complicated to manage&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  Setting up a backoffice load balanced site&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;The following setup applies to both sticky sessions and stateless, with the exception of SignalR which differs between the two and is covered separately at the end.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The assumption here is that the load balanced site will be hosted on Azure as a web app. &lt;br&gt;&#xA;The current documentation will always be the most relevant resource: &lt;a href=&quot;https://docs.umbraco.com/umbraco-cms/fundamentals/setup/server-setup/load-balancing/load-balancing-backoffice&quot; rel=&quot;noopener noreferrer&quot;&gt;https://docs.umbraco.com/umbraco-cms/fundamentals/setup/server-setup/load-balancing/load-balancing-backoffice&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;As of writing this for Umbraco 17, there are some settings that should be set no matter if it is a sticky session or stateless setup:&lt;/p&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Set &lt;code&gt;Umbraco:Cms:Examine:LuceneDirectoryFactory&lt;/code&gt; to &lt;code&gt;TempFileSystemDirectoryFactory&lt;/code&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;Set &lt;code&gt;Umbraco:Cms:Hosting:LocalTempStorageLocation&lt;/code&gt; to &lt;code&gt;EnvironmentTemp&lt;/code&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;Set the &lt;a href=&quot;https://docs.umbraco.com/umbraco-cms/fundamentals/setup/server-setup/load-balancing/load-balancing-backoffice#server-role-accessor&quot; rel=&quot;noopener noreferrer&quot;&gt;Server role accessor&lt;/a&gt; &amp;amp; &lt;a href=&quot;https://docs.umbraco.com/umbraco-cms/fundamentals/setup/server-setup/load-balancing/load-balancing-backoffice#load-balancing-repository-caches&quot; rel=&quot;noopener noreferrer&quot;&gt;IsolatedCaches&lt;/a&gt;:&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight csharp&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;LoadBalancingComposer&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IComposer&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;    &#xA;    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Compose&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IUmbracoBuilder&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;        &#xA;        &lt;span class=&quot;n&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;LoadBalanceIsolatedCaches&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;&#xA;        &lt;span class=&quot;n&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SetServerRegistrar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;StaticServerAccessor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&#xA;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;StaticServerAccessor&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IServerRoleAccessor&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ServerRole&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CurrentServerRole&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ServerRole&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SchedulingPublisher&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;Note: In the traditional setup you&#x27;d have one SchedulingPublisher and multiple Subscribers. With the new backoffice load balancing, check the &lt;a href=&quot;https://docs.umbraco.com/umbraco-cms/fundamentals/setup/server-setup/load-balancing/load-balancing-backoffice#server-role-accessor&quot; rel=&quot;noopener noreferrer&quot;&gt;current documentation&lt;/a&gt; for how server roles should be assigned, as this may differ from what you&#x27;re used to.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;h3&gt;&#xA;  &#xA;  &#xA;  Session management&#xA;&lt;/h3&gt;&#xA;&#xA;&lt;p&gt;If you use sticky sessions then it may seem like nothing is needed for managing sessions as you &quot;stick&quot; to one instance and that instance will handle your session just like on a non-loadbalanced site.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;However, if you consider this scenario:&lt;/p&gt;&#xA;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;You run a webshop with automatic scaling set up &amp;amp; sticky sessions&lt;/li&gt;&#xA;&lt;li&gt;You have a big sale, and the site scales up from 1 to 4 instances&lt;/li&gt;&#xA;&lt;li&gt;A user is assigned to the 4th instance and starts adding things to their basket (which is stored as a session)&lt;/li&gt;&#xA;&lt;li&gt;While that user is browsing traffic lowers, and the automatic scaling scales down to 3 instances&lt;/li&gt;&#xA;&lt;li&gt;The user tries to add a new item to their basket - but the API controller request now hits the load balancer with a sticky session cookie to an instance that has been removed. &lt;/li&gt;&#xA;&lt;li&gt;The load balancer assigns them to a new instance, which has no knowledge of their previous session. Their basket now only contains the item they just added - everything else is gone.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&#xA;&lt;p&gt;The same thing would happen for auth cookies as they use &lt;a href=&quot;https://learn.microsoft.com/en-us/aspnet/core/security/data-protection/introduction?view=aspnetcore-10.0&quot; rel=&quot;noopener noreferrer&quot;&gt;Data Protection&lt;/a&gt; - by default each instance generates its own encryption keys, meaning cookies encrypted on one instance can&#x27;t be decrypted by another. So similarly to the example above, users may need to log in again each time they are moved to a new instance.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Dependent on your site this may not be a big problem, but if you use anything with sessions / auth cookies then it is very bad user experience.&lt;/p&gt;&#xA;&lt;h4&gt;&#xA;  &#xA;  &#xA;  Setting up out of process sessions and data protection&#xA;&lt;/h4&gt;&#xA;&#xA;&lt;p&gt;The solution to both the session and auth cookie problem is to move them out of the individual instances and into a shared store.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;This is needed regardless of whether you use sticky sessions or stateless load balancing:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;With &lt;strong&gt;sticky sessions&lt;/strong&gt;, users are normally pinned to one instance - but as shown in the scenario above, scaling events can force them onto a different instance. Without shared sessions and data protection, that means lost session data and forced re-authentication.&lt;/li&gt;&#xA;&lt;li&gt;With &lt;strong&gt;stateless&lt;/strong&gt; load balancing, every single request can land on a different instance, making shared sessions and data protection essential for even basic functionality.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;In this example we&#x27;ll use Redis, but any &lt;code&gt;IDistributedCache&lt;/code&gt; implementation would work.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;You&#x27;ll need the following NuGet packages:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&quot;https://www.nuget.org/packages/Microsoft.Extensions.Caching.StackExchangeRedis&quot; rel=&quot;noopener noreferrer&quot;&gt;Microsoft.Extensions.Caching.StackExchangeRedis&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&quot;https://www.nuget.org/packages/Microsoft.AspNetCore.DataProtection.StackExchangeRedis&quot; rel=&quot;noopener noreferrer&quot;&gt;Microsoft.AspNetCore.DataProtection.StackExchangeRedis&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;There are three things we need to set up:&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;1. A shared distributed cache&lt;/strong&gt;&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight csharp&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Services&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AddStackExchangeRedisCache&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;options&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;    &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Configuration&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;redisConnectionString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&#xA;    &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;InstanceName&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;my-site-&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;This registers Redis as the &lt;code&gt;IDistributedCache&lt;/code&gt; implementation. By default, ASP.NET Core uses an in-memory implementation which is exactly what causes the problem - each instance has its own cache. By pointing this at a shared Redis instance, all app instances share the same cache.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The &lt;code&gt;InstanceName&lt;/code&gt; is used as a key prefix in Redis, which is useful if you share a Redis instance across multiple applications.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;As a bonus, Umbraco&#x27;s content and media cache is built on Microsoft&#x27;s &lt;a href=&quot;https://docs.umbraco.com/umbraco-cms/reference/configuration/cache-settings&quot; rel=&quot;noopener noreferrer&quot;&gt;HybridCache&lt;/a&gt; - which automatically uses any registered &lt;code&gt;IDistributedCache&lt;/code&gt; as a second-level cache. So by registering Redis here, Umbraco will also use it to share its content and media cache across instances.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;2. Session configuration&lt;/strong&gt;&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight csharp&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Services&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AddSession&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;options&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;    &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IdleTimeout&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TimeSpan&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;FromMinutes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&#xA;    &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Cookie&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;HttpOnly&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&#xA;    &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Cookie&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IsEssential&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&#xA;    &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Cookie&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SecurePolicy&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CookieSecurePolicy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Always&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;ASP.NET Core sessions use whatever &lt;code&gt;IDistributedCache&lt;/code&gt; is registered - so because we registered Redis above, sessions are now automatically stored in Redis instead of in-memory.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The cookie settings are worth noting:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;code&gt;HttpOnly&lt;/code&gt; prevents JavaScript from accessing the session cookie&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;code&gt;IsEssential&lt;/code&gt; ensures the cookie is set even if the user hasn&#x27;t consented to non-essential cookies&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;code&gt;SecurePolicy = Always&lt;/code&gt; ensures the cookie is only sent over HTTPS&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;&lt;strong&gt;3. Shared Data Protection keys&lt;/strong&gt;&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight csharp&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;redisConnection&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ConnectionMultiplexer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Connect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;redisConnectionString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&#xA;&lt;span class=&quot;n&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Services&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AddDataProtection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SetApplicationName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;my-umbraco-site&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;PersistKeysToStackExchangeRedis&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;redisConnection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;DataProtection-Keys&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;This is what solves the auth cookie problem. By default, each instance generates its own Data Protection keys - meaning a cookie encrypted on instance 1 can&#x27;t be decrypted by instance 2.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;By persisting the keys to Redis and setting a shared &lt;code&gt;ApplicationName&lt;/code&gt;, all instances use the same encryption keys. The &lt;code&gt;ApplicationName&lt;/code&gt; is important - instances must share the same application name to be able to decrypt each other&#x27;s cookies.&lt;/p&gt;&#xA;&#xA;&lt;h3&gt;&#xA;  &#xA;  &#xA;  SignalR&#xA;&lt;/h3&gt;&#xA;&#xA;&lt;p&gt;This is the final piece of the puzzle, and the only one where the setup actually differs depending on whether you&#x27;re using sticky sessions or stateless.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Umbraco uses &lt;a href=&quot;https://docs.umbraco.com/umbraco-cms/fundamentals/setup/server-setup/load-balancing/signalr-in-backoffice-load-balanced-environment&quot; rel=&quot;noopener noreferrer&quot;&gt;SignalR&lt;/a&gt; in the backoffice for real-time client-to-server communication outside of standard HTTP requests - for example for preview functionality. In a load balanced setup, SignalR needs a way to send messages across all instances, not just the one the user is connected to. This is called a backplane.&lt;/p&gt;&#xA;&#xA;&lt;h4&gt;&#xA;  &#xA;  &#xA;  Sticky sessions&#xA;&lt;/h4&gt;&#xA;&#xA;&lt;p&gt;With sticky sessions, client-side SignalR connections work as normal - the user has a persistent connection to one instance, just like on a single-server site. The only thing needed is a backplane so that server-side messages (like &quot;this content was just published&quot;) can reach all instances.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Redis works well for this:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight csharp&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// Requires: Microsoft.AspNetCore.SignalR.StackExchangeRedis&lt;/span&gt;&#xA;&lt;span class=&quot;n&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Services&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AddSignalR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AddStackExchangeRedis&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;redisConnectionString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;h4&gt;&#xA;  &#xA;  &#xA;  Stateless&#xA;&lt;/h4&gt;&#xA;&#xA;&lt;p&gt;With stateless load balancing, each request can land on a different instance. SignalR relies on a persistent connection between client and server - and that connection can&#x27;t just &quot;jump&quot; to a new instance on every request. So a Redis backplane alone isn&#x27;t enough here.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The solution is to use a managed SignalR service like Azure SignalR Service, which handles both the backplane and the client-side connections externally:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight csharp&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// Requires: Microsoft.Azure.SignalR&lt;/span&gt;&#xA;&lt;span class=&quot;n&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Services&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AddSignalR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AddAzureSignalR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;azureSignalRConnectionString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;This replaces the need for the Redis backplane entirely for SignalR - Azure SignalR Service handles everything. Note that you still need Redis for the distributed cache, sessions, and data protection as set up above.&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  Wrapping up&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;The stateless approach does give a smoother distribution of load across instances, but Azure SignalR Service adds a significant cost on top of the Redis you already need for everything else.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;In most cases I would go with the sticky session setup - the lower cost and the simplicity of having everything managed through a single Redis instance makes it easy to set up and maintain. And once sessions and data protection are out of process, sticky sessions handle instance swaps gracefully anyway.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;That said, I haven&#x27;t done any load testing to compare the two approaches. If they scale differently under real-world traffic, that could easily be the biggest factor in choosing one over the other. This post is really just meant to highlight the differences and walk through the setup - not to declare a winner. Try both if you can, and pick what fits your situation.&lt;/p&gt;]]></description>
                    <pubDate>Thu, 12 Mar 2026 21:06:17 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://dev.to/luukpeters/upgrade-umbraco-13-to-17-property-editors-property-value-converters-22kb</guid>
                    <title>Upgrade Umbraco 13 to 17: Property Editors &#x2B; Property Value Converters</title>
                    <link>https://dev.to/luukpeters/upgrade-umbraco-13-to-17-property-editors-property-value-converters-22kb</link>
                    <description><![CDATA[&lt;p&gt;This is part five in a series about common tasks you&#x27;ll encounter when upgrading Umbraco 13 to 17. In this part, we&#x2019;ll look at updating Property Editors and Property Value Converters.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;When upgrading several packages, one area that caused confusion was Property Editors. In Umbraco 17 there is a much clearer separation between the UI in the backoffice and the data handling and validation on the backend (C#).&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Because of this change, Umbraco introduced migrations that convert existing Data Types (which are essentially instances of a Property Editor) to the new format. In Umbraco 13 a Data Type only referenced a single editor alias, but in Umbraco 17 it contains two: an &lt;strong&gt;editor alias&lt;/strong&gt; (backend) and an &lt;strong&gt;editor UI alias&lt;/strong&gt; (frontend). This makes it possible, for example, to use multiple interchangeable UIs that work with the same underlying data.&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  Why won&#x27;t my property editor work anymore?&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;After upgrading my database to Umbraco 17 I ran into a couple of issues:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;How does Umbraco know that it should use my newly created Property Editor UI for existing properties?&lt;/li&gt;&#xA;&lt;li&gt;Why does Models Builder suddenly return a &lt;code&gt;JsonDocument&lt;/code&gt; instead of my custom &lt;code&gt;VideoPlayerValueConverterModel&lt;/code&gt;?&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;The answer lies in understanding what the migration from Umbraco 13 to 14&#x2B; actually does and what you need to do with the result. This post walks through that process.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;This blog explains how you can update your Property Editors to work in Umbraco 17 without having to create a custom migration. It also helps to read the &lt;a href=&quot;https://docs.umbraco.com/umbraco-cms/customizing/property-editors/composition&quot; rel=&quot;noopener noreferrer&quot;&gt;Umbraco documentation on Property Editor composition&lt;/a&gt;. That documentation explains the different pieces that make up a Property Editor in Umbraco 17 and provides useful context for what follows.&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  The starting point before the migration&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;There are two different starting points for Property Editors in Umbraco 13, and each leads to a slightly different outcome during the migration to Umbraco 14&#x2B;. The difference depends on whether the Property Editor is defined in a &lt;strong&gt;package.manifest&lt;/strong&gt; file or in &lt;strong&gt;C# code&lt;/strong&gt;.&lt;/p&gt;&#xA;&#xA;&lt;h3&gt;&#xA;  &#xA;  &#xA;  Starting point 1: manifest-only Property Editor&#xA;&lt;/h3&gt;&#xA;&#xA;&lt;p&gt;In Umbraco 13 a Property Editor can be defined purely in a &lt;code&gt;package.manifest&lt;/code&gt;, for example:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight json&quot;&gt;&lt;code&gt;&lt;span class=&quot;err&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;propertyEditors&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;alias&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;proudnerds.videoplayer.editor&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Video player&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;icon&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;icon-play&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;group&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Proud Nerds&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;editor&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;        &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;view&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;~/App_Plugins/ProudNerds.Umbraco.VideoPlayer/umbraco.videoplayer.html&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;      &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;This is enough to create a simple data editor. The value is stored as a string in the database and there is no server-side validation. Anything can be stored as long as it fits into a string.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;If needed, you can still transform that value later using a Property Value Converter before it ends up in the cache.&lt;/p&gt;&#xA;&#xA;&lt;h3&gt;&#xA;  &#xA;  &#xA;  Starting point 2: Property Editor defined in code&#xA;&lt;/h3&gt;&#xA;&#xA;&lt;p&gt;You can also &lt;a href=&quot;https://docs.umbraco.com/umbraco-cms/13.latest/tutorials/creating-a-property-editor#setting-up-a-property-editor-with-csharp&quot; rel=&quot;noopener noreferrer&quot;&gt;define a Property Editor in C#&lt;/a&gt;, for example:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight csharp&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Umbraco.Cms.Core.PropertyEditors&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&#xA;&#xA;&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;YourProjectName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&#xA;&#xA;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;DataEditor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&#xA;    &lt;span class=&quot;k&quot;&gt;alias&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Suggestions editor&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&#xA;    &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Suggestions&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&#xA;    &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;/App_Plugins/Suggestions/suggestion.html&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&#xA;    &lt;span class=&quot;n&quot;&gt;Group&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Common&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&#xA;    &lt;span class=&quot;n&quot;&gt;Icon&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;icon-list&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;&#xA;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Suggestions&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DataEditor&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Suggestions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IDataValueEditorFactory&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dataValueEditorFactory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&#xA;        &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;base&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dataValueEditorFactory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;            &#xA;    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;Defining a Property Editor in code gives you more control over validation and how the data is stored.&lt;/p&gt;&#xA;&#xA;&lt;h3&gt;&#xA;  &#xA;  &#xA;  The resulting database records&#xA;&lt;/h3&gt;&#xA;&#xA;&lt;p&gt;When you create a Data Type in Umbraco 13 that uses a Property Editor, the resulting database record is almost identical for both approaches. Each Data Type simply stores a property editor alias and configuration in the &lt;code&gt;umbracoDataType&lt;/code&gt; table.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&quot;https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuicwlvzwi8diylzqvd6h.png&quot; class=&quot;article-body-image-wrapper&quot;&gt;&lt;img src=&quot;https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuicwlvzwi8diylzqvd6h.png&quot; alt=&quot; &quot; width=&quot;631&quot; height=&quot;167&quot;&gt;&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;p&gt;If you register the editor in C#, the &lt;code&gt;dbType&lt;/code&gt; may differ, but that detail is not important for this discussion.&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  The data migration (13 &#x2192; 14&#x2B;)&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;The difference between the two approaches becomes visible during migration.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;In one of the later Umbraco 13 versions a &lt;strong&gt;pre-migration&lt;/strong&gt; was introduced that prepares Property Editors for upgrading to Umbraco 14&#x2B;. During this step, a record is written to the &lt;code&gt;umbracoKeyValue&lt;/code&gt; table describing how each Data Type should be migrated.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;For a manifest-only Property Editor, the record looks like this:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight json&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;[{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;DataTypeId&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1055&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;EditorUiAlias&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;proudnerds.videoplayer.editor&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;EditorAlias&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Umbraco.Plain.String&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;However, if the editor was defined in C#, both aliases will be the same:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight json&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;[{&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;DataTypeId&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1055&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;EditorUiAlias&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;proudnerds.videoplayer.editor&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;EditorAlias&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;proudnerds.videoplayer.editor&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;After the database upgrade to Umbraco 17, this information is used to populate the new &lt;code&gt;propertyEditorAlias&lt;/code&gt; and &lt;code&gt;propertyEditorUiAlias&lt;/code&gt; columns in the &lt;code&gt;umbracoDataType&lt;/code&gt; table.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;For the video player editor, the result of the migration looks like this:&lt;/p&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&quot;https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F58t3d0gffuy81n6oww8m.png&quot; class=&quot;article-body-image-wrapper&quot;&gt;&lt;img src=&quot;https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F58t3d0gffuy81n6oww8m.png&quot; alt=&quot; &quot; width=&quot;772&quot; height=&quot;148&quot;&gt;&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  Updating the code&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Once you understand what the migration produced in the database, updating the code becomes much clearer.&lt;/p&gt;&#xA;&#xA;&lt;h3&gt;&#xA;  &#xA;  &#xA;  Creating and registering the Property Editor UI&#xA;&lt;/h3&gt;&#xA;&#xA;&lt;p&gt;With the new backoffice introduced in Umbraco 14&#x2B;, the UI part of your Property Editor needs to be recreated because AngularJS is no longer supported.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;After creating the UI, you need to register it. I won&#x27;t go into the details of building a Property Editor UI here (the &lt;a href=&quot;https://docs.umbraco.com/umbraco-cms/customizing/property-editors/composition/property-editor-ui&quot; rel=&quot;noopener noreferrer&quot;&gt;documentation&lt;/a&gt; covers that), but the aliases you use during registration are important.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Based on the migration result:&lt;/p&gt;&#xA;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;code&gt;alias&lt;/code&gt; should match &lt;strong&gt;PropertyEditorUiAlias&lt;/strong&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;code&gt;propertyEditorSchemaAlias&lt;/code&gt; should match &lt;strong&gt;PropertyEditorAlias&lt;/strong&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&#xA;&lt;p&gt;For example:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight typescript&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;manifests&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;UmbExtensionManifest&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;    &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&#x27;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;propertyEditorUi&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&#x27;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&#xA;    &lt;span class=&quot;na&quot;&gt;alias&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;proudnerds.videoplayer.editor&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&#xA;    &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Proud Nerds video player property editor&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&#xA;    &lt;span class=&quot;na&quot;&gt;js&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;./proud-nerds-video-property-editor-ui.element&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;&#xA;    &lt;span class=&quot;na&quot;&gt;meta&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;        &lt;span class=&quot;na&quot;&gt;label&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Video player&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&#xA;        &lt;span class=&quot;na&quot;&gt;icon&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;icon-play&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&#xA;        &lt;span class=&quot;na&quot;&gt;group&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Proud Nerds&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&#xA;        &lt;span class=&quot;na&quot;&gt;propertyEditorSchemaAlias&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Umbraco.Plain.Json&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&#xA;        &lt;span class=&quot;na&quot;&gt;settings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&#xA;            &lt;span class=&quot;na&quot;&gt;properties&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&#xA;                &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;&#xA;            &lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&#xA;        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;h3&gt;&#xA;  &#xA;  &#xA;  Updating the DataEditor (if it already exists)&#xA;&lt;/h3&gt;&#xA;&#xA;&lt;p&gt;If your editor already had a &lt;code&gt;DataEditor&lt;/code&gt; implementation, you can continue using it, but it needs to be updated for Umbraco 17.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Most of the implementation remains similar to Umbraco 13. The main difference is that several parameters have been removed from the &lt;code&gt;DataEditor&lt;/code&gt; attribute because of the clearer separation between UI and backend logic.&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight csharp&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// Umbraco 13&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;DataEditor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&#xA;    &lt;span class=&quot;k&quot;&gt;alias&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;proudnerds.videoplayer.editor&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&#xA;    &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Video Player&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&#xA;    &lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;/App_Plugins/VideoPlayer/videoplayer.html&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&#xA;    &lt;span class=&quot;n&quot;&gt;Group&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Proud Nerds&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&#xA;    &lt;span class=&quot;n&quot;&gt;Icon&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;icon-play&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;&#xA;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;VideoPlayerEditor&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DataEditor&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;&#xA;&#xA;&lt;span class=&quot;c1&quot;&gt;// Umbraco 17&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;DataEditor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;proudnerds.videoplayer.editor&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;&#xA;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;VideoPlayerEditor&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DataEditor&lt;/span&gt;&#xA;&lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;h3&gt;&#xA;  &#xA;  &#xA;  Updating the Property Value Converter (if needed)&#xA;&lt;/h3&gt;&#xA;&#xA;&lt;p&gt;If you used the manifest-only approach in Umbraco 13, there is a good chance your Property Value Converter no longer works.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;During migration, the &lt;code&gt;EditorAlias&lt;/code&gt; for the video editor changed from:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight plaintext&quot;&gt;&lt;code&gt;proudnerds.videoplayer.editor&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;to:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight plaintext&quot;&gt;&lt;code&gt;Umbraco.Plain.Json&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;So if your Property Value Converter checks the editor alias, it will no longer match:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight csharp&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;IsConverter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IPublishedPropertyType&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;propertyType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt;&#xA;&lt;span class=&quot;n&quot;&gt;propertyType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;EditorAlias&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Equals&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;proudnerds.videoplayer.editor&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;The simplest fix is to check the &lt;strong&gt;EditorUiAlias&lt;/strong&gt; instead:&lt;br&gt;&#xA;&lt;/p&gt;&#xA;&#xA;&lt;div class=&quot;highlight js-code-highlight&quot;&gt;&#xA;&lt;pre class=&quot;highlight csharp&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;IsConverter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IPublishedPropertyType&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;propertyType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt;&#xA;&lt;span class=&quot;n&quot;&gt;propertyType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;EditorUiAlias&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Equals&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;proudnerds.videoplayer.editor&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&#xA;&lt;p&gt;This is not entirely semantically correct, but it is often the easiest solution without introducing additional migrations. After this, your Property Editor will work as expected again and the models builder will use your custom model instead of the generic JsonDocument.&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  Done&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Once you understand how the Property Editor migration works, it becomes much easier to determine which aliases to use in &lt;code&gt;umbraco-package.json&lt;/code&gt; and what code changes are required after upgrading.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;The concepts themselves are straightforward, but the migration can be confusing the first time you encounter it. Hopefully this overview helps clarify what is happening behind the scenes.&lt;/p&gt;&#xA;&#xA;&lt;h2&gt;&#xA;  &#xA;  &#xA;  EditorUiAlias or not?&#xA;&lt;/h2&gt;&#xA;&#xA;&lt;p&gt;Earlier I mentioned that checking &lt;code&gt;EditorUiAlias&lt;/code&gt; inside the &lt;code&gt;IsConverter&lt;/code&gt; method of a Property Value Converter is not entirely correct from a semantic point of view.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;A Property Value Converter operates on the data stored in the database and converts that to something else to put in the cache. A Property Editor UI is only the interface used to edit that data. In fact, multiple UIs could theoretically exist for the same underlying editor.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Because of that, checking &lt;code&gt;EditorUiAlias&lt;/code&gt; introduces some risk. If a different UI were introduced for the same editor, your converter might no longer match the correct data. Checking &lt;code&gt;EditorAlias&lt;/code&gt; is the safest way to guarantee you are handling the expected data structure.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;That said, in many real-world scenarios a Property Editor has exactly one UI and one DataEditor that always belong together. If you fully control the implementation, checking &lt;code&gt;EditorUiAlias&lt;/code&gt; can be a pragmatic and perfectly workable solution that avoids writing additional migrations.&lt;/p&gt;&#xA;&#xA;&lt;p&gt;Opinions on this tend to differ. Some developers strongly prefer to always check &lt;code&gt;EditorAlias&lt;/code&gt; for correctness, while others consider &lt;code&gt;EditorUiAlias&lt;/code&gt; acceptable when the editor and UI are tightly coupled. In the end, the choice depends on how strictly you want to follow the separation between UI and data.&lt;/p&gt;]]></description>
                    <pubDate>Thu, 12 Mar 2026 13:30:20 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://www.youtube.com/watch?v=_RUYI1xNzdE</guid>
                    <title>DevRel Deep Dive: Exploring Umbraco.AI with Matt Brailsford</title>
                    <link>https://www.youtube.com/watch?v=_RUYI1xNzdE</link>
                    <description><![CDATA[This week Sebastiaan and Lotte are joined by Matt Brailsford, Staff Engineer at Umbraco, to show Umbraco.AI in action. Umbraco.AI is Umbraco&#x2019;s free and open source AI foundation and integration add-on for the CMS. It&#x2019;s provider-agnostic, with NuGet packages for OpenAI, Anthropic and more. They also look at the other two main packages that Umbraco HQ has developed: Umbraco.AI.Prompt and Umbraco.AI.Agent. Watch, learn, and then try them for yourself!&#xA;&#xA;&#x1F4D6; Matt&#x2019;s &quot;kitchen sink&quot; getting started blog post: https://mattbrailsford.dev/umbraco-ai-kitchen-sink-install&#xA;&#x1F440; Umbraco.AI source code on GitHub: https://github.com/umbraco/Umbraco.AI&#xA;&#xA;--------&#xA;&#x2753; Looking for help with your Umbraco projects? Visit the Forum&#xA; https://forum.umbraco.com&#xA; &#xA;&#x1F4AC; Want to chat with the friendly Umbraco Community? Join our Discord server&#xA; https://discord.umbraco.com&#xA; &#xA;&#x2709;&#xFE0F; Got a question (or topic suggestion) for the HQ Developer Relations team?&#xA; https://umbra.co/contact-devrel, or the &#x2018;contact-devrel&#x2019; channel on Discord&#xA; &#xA;#Umbraco]]></description>
                    <pubDate>Thu, 12 Mar 2026 10:24:56 Z</pubDate>
                        <category>community</category>
                        <category>youtube</category>
                </item>
                <item>
                    <guid>https://medium.com/@glenstark883/boost-your-website-with-expert-umbraco-development-services-3ca0c166f387?source=rss------umbraco-5</guid>
                    <title>Boost Your Website with Expert Umbraco Development Services</title>
                    <link>https://medium.com/@glenstark883/boost-your-website-with-expert-umbraco-development-services-3ca0c166f387?source=rss------umbraco-5</link>
                    <description><![CDATA[&lt;div class=&quot;medium-feed-item&quot;&gt;&lt;p class=&quot;medium-feed-image&quot;&gt;&lt;a href=&quot;https://medium.com/@glenstark883/boost-your-website-with-expert-umbraco-development-services-3ca0c166f387?source=rss------umbraco-5&quot;&gt;&lt;img src=&quot;https://cdn-images-1.medium.com/max/1536/1*zGapSohko4R6HMLCG_1Vqw.png&quot; width=&quot;1536&quot;&gt;&lt;/a&gt;&lt;/p&gt;&lt;p class=&quot;medium-feed-snippet&quot;&gt;In today&amp;#x2019;s competitive digital landscape, businesses need websites that are fast, scalable, and easy to manage.&lt;/p&gt;&lt;p class=&quot;medium-feed-link&quot;&gt;&lt;a href=&quot;https://medium.com/@glenstark883/boost-your-website-with-expert-umbraco-development-services-3ca0c166f387?source=rss------umbraco-5&quot;&gt;Continue reading on Medium &#xBB;&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;]]></description>
                    <pubDate>Thu, 12 Mar 2026 07:55:23 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://www.youtube.com/watch?v=1vCk_13FGsQ</guid>
                    <title>AI in Umbraco: Feature demo</title>
                    <link>https://www.youtube.com/watch?v=1vCk_13FGsQ</link>
                    <description><![CDATA[AI in Umbraco: &#xA;Bolette Kern (CMS Product Manager) and Matt Brailsford (Staff Engineer) provide a deep dive into the rapid evolution of AI in Umbraco following the 2026 Winter Keynote. This update showcases how AI has transitioned from a nested setting to a core, dedicated section of the Umbraco back office, offering better organization and granular permission control for developers and content editors.&#xA;&#xA;The session covers significant functional upgrades to AI prompts and agents, including the ability to generate multiple content variations and the introduction of &quot;Auto Agents&quot; that intelligently select the best tool for your specific request. You will also get an exclusive first look at the upcoming Evaluation and Testing dashboard, designed to help organizations benchmark AI performance, accuracy, and cost.&#xA;&#xA;This video is for Umbraco developers, architects, and content strategists looking to leverage AI within their CMS workflows. Whether you are building custom AI integrations or using HQ packages, these updates provide the foundation for secure, scalable, and context-aware AI implementations.&#xA;&#xA;Video Chapters:&#xA;00:00 Introduction with Bolette Kern and Matt Brailsford&#xA;00:55 The New Dedicated AI Back Office Section&#xA;02:14 Enhanced Prompts: Generating Multiple Options&#xA;03:25 AI Agents vs. Prompts: Key Differences&#xA;04:05 Security: Permissions, Scopes, and User Group Overrides&#xA;05:30 Context Awareness and Location-Based Agents&#xA;06:35 The Auto Agent: Intelligent Prompt Routing&#xA;07:58 Preview: The AI Testing and Evaluation Dashboard&#xA;12:56 Developer Updates: Deploy, Notifications, and Field Validation&#xA;14:37 Future Outlook and Community Hackathons&#xA;&#xA;Key Takeaways:&#xA;- Dedicated AI Workspace: AI now resides in its own back office section, improving discoverability and allowing for specific user permissions independent of the settings section.&#xA;&#xA;- Iterative Content Generation: Prompts can now return up to five different options simultaneously, allowing editors to compare and select the best result.&#xA;&#xA;- Granular Security: The new Scopes system allows administrators to group AI tools and manage access at the user group level for fine-grained control.&#xA;&#xA;- Intelligent Routing: The Auto Agent feature analyzes user intent to automatically trigger the most relevant specialist, such as a Legal Assistant or a Content Creator.&#xA;&#xA;- Quality Assurance: The upcoming Testing section allows for &quot;mock data&quot; evaluations and &quot;graders&quot; to ensure AI responses remain consistent as models evolve.&#xA;&#xA;Resources and Links: &#xA;Umbraco AI Product Page: https://umbraco.com/ai/&#xA;&#xA;Umbraco Winter Keynote (Reference): https://youtu.be/GK-eGhzZYpw&#xA;&#xA;Latest Release Blog Post: https://umbraco.com/blog/the-agent-ready-cms-what-are-agent-skills/&#xA;&#xA;Umbraco Marketplace: https://marketplace.umbraco.com/package/umbraco.ai&#xA;&#xA;Developer Events and Hackathons: https://www.meetup.com/pro/umbraco/]]></description>
                    <pubDate>Thu, 12 Mar 2026 07:16:58 Z</pubDate>
                        <category>hq</category>
                        <category>youtube</category>
                </item>
                <item>
                    <guid>https://umbraco.com/blog/umbraco-product-update-q1-2026/</guid>
                    <title>Umbraco Product Update - Q1 2026</title>
                    <link>https://umbraco.com/blog/umbraco-product-update-q1-2026/</link>
                    <description><![CDATA[Explore this update featuring the launch of Umbraco Compose, a new AI strategy, enhanced security in Umbraco Cloud, and a new era for Search.]]></description>
                    <pubDate>Thu, 12 Mar 2026 00:00:00 Z</pubDate>
                        <category>hq</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/modgift.umbraco.imageupload</guid>
                    <title>Modgift.Umbraco.ImageUpload</title>
                    <link>https://marketplace.umbraco.com/package/modgift.umbraco.imageupload</link>
                    <description><![CDATA[Automatically resizes and converts images uploaded to Umbraco CMS 17 media library.]]></description>
                    <pubDate>Thu, 12 Mar 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://umbraco.com/blog/umbraco-cms-security-advisory-march-10-2026-security-patches-are-now-available/</guid>
                    <title>Umbraco CMS Security Advisory, March 10, 2026</title>
                    <link>https://umbraco.com/blog/umbraco-cms-security-advisory-march-10-2026-security-patches-are-now-available/</link>
                    <description><![CDATA[Security patches are available for Umbraco versions 16 and 17 to fix three moderate-to-high vulnerabilities. Upgrade now to secure your CMS. Projects on Umbraco Cloud will automatically receive the fixes.]]></description>
                    <pubDate>Tue, 10 Mar 2026 00:00:00 Z</pubDate>
                        <category>hq</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://owain.codes/blog/2026/march/auto-updating-your-github-readme-with-your-latest-blog-posts/</guid>
                    <title>Auto-Updating Your GitHub README with Your Latest Blog Posts</title>
                    <link>https://owain.codes/blog/2026/march/auto-updating-your-github-readme-with-your-latest-blog-posts/</link>
                    <description><![CDATA[]]></description>
                    <pubDate>Tue, 10 Mar 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>blog</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/umbraco.community.uschema</guid>
                    <title>Umbraco.Community.uSchema</title>
                    <link>https://marketplace.umbraco.com/package/umbraco.community.uschema</link>
                    <description><![CDATA[Validates JSON-LD structured data on published Umbraco content pages via a workspace tab in the backoffice.]]></description>
                    <pubDate>Tue, 10 Mar 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://marketplace.umbraco.com/package/backofficethemes</guid>
                    <title>BackofficeThemes</title>
                    <link>https://marketplace.umbraco.com/package/backofficethemes</link>
                    <description><![CDATA[Extra themes for the Umbraco backoffice &#x2014; including Christmas (theme plus snow, lights, tree, Santa hat) and popular editor-style themes: Neon, Cyberpunk, Dracula, Monokai, VS Blue, VS Cool Breeze, and VS Icy Mint.]]></description>
                    <pubDate>Mon, 09 Mar 2026 00:00:00 Z</pubDate>
                        <category>community</category>
                        <category>package</category>
                        <category>marketplace</category>
                </item>
                <item>
                    <guid>https://umbracocommunity.social/@umbraco/116182281314587750</guid>
                    <title>One week left to submit your Umbraco Awards 2026 entry!</title>
                    <link>https://umbracocommunity.social/@umbraco/116182281314587750</link>
                    <description><![CDATA[One week left to submit your Umbraco Awards 2026 entry! &#x1F570;&#xFE0F; No video needed - just the facts. Partners can turn entries into https://umbraco.com case studies for extra exposure. Streamlined form, minimal effort. Deadline: March 13. Submit: https://umbra.co/4l7zW42 #Umbraco]]></description>
                    <pubDate>Fri, 06 Mar 2026 15:32:53 Z</pubDate>
                        <category>social</category>
                        <category>mastodon</category>
                        <category>hq</category>
                </item>
                <item>
                    <guid>https://discord.com/channels/869656431308189746/882981290662580264/1479418096111583373</guid>
                    <title>ValidationAttributes package now under the Umbraco Community GitHub account</title>
                    <link>https://discord.com/channels/869656431308189746/882981290662580264/1479418096111583373</link>
                    <description><![CDATA[With blessings from the original author we have taken the ValidationAttributes package for Umbraco and forked it into a repo under the Umbraco Community GitHub account.&#xA;&#xA;I have released a stable for V17 that can be download now!&#xA;&#xA;https://marketplace.umbraco.com/package/umbraco.community.validationattributes&#xA;&#xA;#umbraco #community]]></description>
                    <pubDate>Fri, 06 Mar 2026 09:59:31 Z</pubDate>
                        <category>community</category>
                        <category>social</category>
                        <category>discord</category>
                </item>
    </channel>
</rss>