This guide walks through setting up a new Umbraco package project called Umbraco.Community.AI.Woowoo that extends Umbraco.AI. 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.
That's where Lotte's Opinionated Package Starter Template 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 dotnet new template. Pair that with Matt Brailsford's Umbraco.AI Kitchen Sink install guide, and you have everything you need to go from zero to a fully wired-up Umbraco.AI development environment.
This post walks through the full setup end-to-end.
Why this is a "v17" post now. Umbraco 18 has shipped, which means the unversioned commands in the original guide (
dotnet new install …,dotnet add package …) now resolve to 18.x and give you a mismatched, non-booting solution. This updated version pins every install to the latest v17 release (17.5.3 at time of writing) and adds two fixes that only surface once all the pieces are aligned. Every command below was run and verified end-to-end on .NET 10 / Umbraco 17.5.3.
Prerequisites
Before starting, make sure you have:
- .NET 10 SDK -- Umbraco 17 targets .NET 10
- Node.js and npm -- the package project uses Vite and TypeScript for its frontend
- A GitHub account -- the template wires up a GitHub remote and includes GitHub Actions for NuGet publishing
Step 1: Install the Umbraco CMS template (pinned to v17)
The Package Starter template scaffolds a test site and runs dotnet new umbraco-extension under the hood, so it needs Umbraco's official templates to be available first. Pin to a v17 release -- an unpinned install now pulls Umbraco 18:
dotnet new install Umbraco.Templates::17.5.3 --force
--force reinstalls over any existing version. Pinning to 17.5.3 guarantees the umbraco-extension template scaffolds the package project against Umbraco 17, not 18.
Step 2: Install the package starter template
The starter template's latest release is already a v17 build, but pin it anyway for reproducibility:
dotnet new install Umbraco.Community.Templates.PackageStarter::17.1.1
What does this template give you?
When you scaffold from it, you get a complete two-project solution:
-
src/AI.Woowoo/-- the package project, with Vite + TypeScript frontend (via theumbraco-extensiontemplate) and a NuGet-configured.csproj -
src/AI.Woowoo.TestSite/-- an Umbraco 17 test site with uSync pre-configured -
src/AI.Woowoo.slnx-- the solution file, with the TestSite already referencing the package project -
.github/workflows/release.yml-- a GitHub Action that publishes to NuGet when you push a version tag -
umbraco-marketplace.json, README stubs, issue templates, and an MITLICENSE
Step 3: Scaffold the solution
dotnet new umbracopackagestarter -n AI.Woowoo -an "Your Name" -gu YourGitHubUsername -gr Umbraco.Community.AI.Woowoo --allow-scripts yes
What each parameter does:
| Parameter | What it does |
|---|---|
-n AI.Woowoo |
The base name for the solution. The template prepends Umbraco.Community., so the NuGet package ID becomes Umbraco.Community.AI.Woowoo
|
-an "Your Name" |
Author name, used in the .csproj and marketplace metadata |
-gu YourGitHubUsername |
Your GitHub username, used to construct the repo URL |
-gr Umbraco.Community.AI.Woowoo |
The GitHub repository name |
--allow-scripts yes |
Bypasses the security prompt for the post-creation script (setup.cmd on Windows, setup.sh on Linux/macOS), which initializes git, ensures the Umbraco templates are installed, and scaffolds the umbraco-extension project |
⚠️ Expect this step to fail its post-action — and repair it
The starter's post-creation script (setup.sh/setup.cmd) contains this line:
dotnet new install Umbraco.Templates --force
It runs while the outer dotnet new is still executing, and that concurrent write to the template store is a problem in two ways:
- It's unpinned, so it wants to pull the latest templates — which is now 18.x.
- Running a template install inside a template post-action corrupts the template store. In my testing this happens on every fresh run: the scaffold ends with
Restore failed. / Post action failed, and the package project comes out with noClient/folder and noDirectory.Packages.props— theumbraco-extensionsub-scaffold never actually ran.
The trap: after this,
dotnet new uninstallmay still listUmbraco.Templatesas17.5.3, so it looks fine. It isn't — the mount is broken, anddotnet new umbraco-extensionfails with "No templates found matching: 'umbraco-extension'." Don't trust the version number; repair unconditionally.
The repair — run these regardless of what the version looks like:
# 1. Always re-install the templates to repair the corrupted store (this also
# re-pins you to v17, undoing setup.sh's attempt to move you to 18).
dotnet new install Umbraco.Templates::17.5.3 --force
# 2. Keep the NuGet-flavoured .csproj the starter created — the re-scaffold below
# would otherwise overwrite it and you'd lose PackageId / author / README metadata.
cp src/AI.Woowoo/AI.Woowoo.csproj /tmp/AI.Woowoo.nuget.csproj
# 3. Re-run the extension scaffold the setup script was supposed to run, pinned to v17.
# This creates Client/, Directory.Packages.props (17.5.3), Composers/, Controllers/, Constants.cs.
dotnet new umbraco-extension -n AI.Woowoo -o src/AI.Woowoo \
--site-domain "https://localhost:44300" --include-example --force
# 4. Restore the NuGet-flavoured .csproj (step 3 overwrote it with the plain one).
cp /tmp/AI.Woowoo.nuget.csproj src/AI.Woowoo/AI.Woowoo.csproj
On Windows, swap the two
cplines forcopy, and use a real temp path (e.g.%TEMP%\AI.Woowoo.nuget.csproj).
Verify the package project landed on v17 before moving on:
ls src/AI.Woowoo/Client # lists package.json, src/, vite.config.ts, …
grep Umbraco.Cms src/AI.Woowoo/Directory.Packages.props # the four versions should read 17.5.3
grep backoffice src/AI.Woowoo/Client/package.json # "@umbraco-cms/backoffice": "^17.5.3"
grep PackageId src/AI.Woowoo/AI.Woowoo.csproj # <PackageId>Umbraco.Community.AI.Woowoo</PackageId>
If Client/ exists, Directory.Packages.props shows 17.5.3, and the .csproj still has its PackageId, the repair worked and you have a clean v17 package project.
Step 4: Build the frontend & verify the base site
Neither template runs npm install -- that's an explicit manual step. Build the frontend assets first:
cd src/AI.Woowoo/Client
npm install
npm run build
You should see Vite output with files written to ../wwwroot/App_Plugins/AIWoowoo/. Now start the TestSite:
cd ../../AI.Woowoo.TestSite
dotnet run
On first run, Umbraco installs itself unattended -- watch the terminal for the URL (https://localhost:44356 by default). Log in with the pre-configured credentials from appsettings.json:
-
Email:
admin@example.com -
Password:
1234567890
Confirm the Example Dashboard shows under Content, and that /umbraco/swagger lists the Umbraco Management API. Then Ctrl+C to stop.
Step 5: Add the Umbraco.AI packages (pinned to v17)
All the Umbraco.AI packages go into the TestSite project. This is the single biggest change from the original post: every one of these packages now has both a 17.x and an 18.x line on NuGet, and an unpinned dotnet add package grabs 18.x -- which drags in Umbraco 18 and breaks the build. Pin them all to 17.x.
The same applies to the Clean starter kit: Clean 8.x requires Umbraco 18, so pin it to 7.0.8 (the latest 7.x, which targets Umbraco.Cms.Web.Website [17.5.1, )).
Run these from the repo root (AI.Woowoo/):
# The Clean starter kit adds a demo content structure to the site
dotnet add "src/AI.Woowoo.TestSite" package Clean -v 7.0.8
# The core Umbraco.AI integration layer
dotnet add "src/AI.Woowoo.TestSite" package Umbraco.AI -v 17.1.1
# Addons
dotnet add "src/AI.Woowoo.TestSite" package Umbraco.AI.Prompt -v 17.1.0
dotnet add "src/AI.Woowoo.TestSite" package Umbraco.AI.Agent -v 17.1.0
dotnet add "src/AI.Woowoo.TestSite" package Umbraco.AI.Agent.Copilot -v 17.0.0
# AI providers
dotnet add "src/AI.Woowoo.TestSite" package Umbraco.AI.Amazon -v 17.0.0
dotnet add "src/AI.Woowoo.TestSite" package Umbraco.AI.Anthropic -v 17.0.0
dotnet add "src/AI.Woowoo.TestSite" package Umbraco.AI.Google -v 17.0.0
dotnet add "src/AI.Woowoo.TestSite" package Umbraco.AI.MicrosoftFoundry -v 17.0.0
dotnet add "src/AI.Woowoo.TestSite" package Umbraco.AI.OpenAI -v 17.1.0
On v17,
Umbraco.AI.Agent.Copilothas a stable17.0.0release, so you no longer need the--prereleaseflag the original post used.
⚠️ Bump the TestSite to Umbraco 17.5.3
The starter template hard-codes the TestSite to Umbraco.Cms 17.0.0. That was fine when the umbraco-extension template was also 17.0.0 -- but the template (and therefore your package's frontend and the Umbraco.AI backoffice bundles) now target the 17.5.x backoffice API. Running that frontend against a 17.0.0 backoffice throws TypeError: authContext.configureClient is not a function (the configureClient method was added to the backoffice auth context after 17.0.0), the API client never gets its auth token, and every Umbraco.AI screen 401s and shows "No items" even though the data is there.
The fix is to align the runtime with the frontend. Edit src/AI.Woowoo.TestSite/AI.Woowoo.TestSite.csproj:
<PackageReference Include="Umbraco.Cms" Version="17.5.3" />
Step 6: Add the seed demo data
Matt's Gist seeds a full Umbraco.AI demo configuration (a connection, profile, context, prompts, and agents). It's idempotent and self-registering:
curl -o src/AI.Woowoo.TestSite/UmbracoAISeedData.cs \
"https://gist.githubusercontent.com/mattbrailsford/199d0b45e926ffb122fa96467039bd90/raw/e8f16509b876562b442a641b1bfc3b50a4defd1c/UmbracoAISeedData.cs"
The seed installs an OpenAI connection with a dummy key (YOUR_OPENAI_API_KEY); the site runs fine without a real one -- replace it later in the backoffice. (No curl? On Windows use Invoke-WebRequest, or just save the URL in your browser.)
Step 7: Bootstrap ModelsBuilder (required for the Clean views)
This step is new, and it's mandatory once the Clean starter kit is installed. Clean ships strongly-typed Razor views (home.cshtml, article.cshtml, …) that inherit from UmbracoViewPage<ContentModels.Home> and friends. Those PublishedModels.* classes don't exist until ModelsBuilder generates them from the document types -- but the document types only exist in the database after the site has run. Classic chicken-and-egg: the build fails before the app can start to generate the models. (See the companion post: Bootstrapping Umbraco ModelsBuilder on an empty site.)
1. Switch ModelsBuilder to a mode that gives you a "Generate models" button. In src/AI.Woowoo.TestSite/appsettings.json:
"ModelsBuilder": {
"ModelsMode": "SourceCodeManual"
}
(The starter template ships "Nothing", which never generates models at all.)
2. Temporarily skip Razor compile-on-build so the site can boot. In src/AI.Woowoo.TestSite/AI.Woowoo.TestSite.csproj:
<RazorCompileOnBuild>false</RazorCompileOnBuild>
3. Run, then generate the models from the backoffice → Settings → Models Builder → Generate models. You'll get ~45 *.generated.cs files under src/AI.Woowoo.TestSite/umbraco/models/.
cd src/AI.Woowoo.TestSite
dotnet run
4. Stop the site (Ctrl+C), remove the RazorCompileOnBuild line you added in step 2, and run again. The views now compile against the generated models and the front-end renders.
Step 8: Run and verify
cd src/AI.Woowoo.TestSite
dotnet run
Log in (admin@example.com / 1234567890) and check:
- The front-end (
https://localhost:44356/) renders the Clean starter home page. - The Umbraco.AI section shows a seeded OpenAI connection (Active), a profile, a context, several prompts, and several agents (Content Assistant, Legal Specialist, Media Assistant, …).
- Browser console is clean -- no
configureClienterrors.
The seeded data may not appear in the AI collection lists until the second startup -- the seeder writes on first boot, and the collection views pick it up on the next run.
Step 9: Make the initial commit
Sanity-check that UmbracoAISeedData.cs has no real API key, then:
git add .
git commit -m "chore: initial scaffold from Lotte's Opinionated Package Starter Template"
git push -u origin main
Create an empty GitHub repo named
Umbraco.Community.AI.Woowoofirst (no readme/license/gitignore). The template already configured the remote.
Verified version matrix (Umbraco 17, July 2026)
| Component | Pin used | Unpinned would give |
|---|---|---|
Umbraco.Templates |
17.5.3 |
18.0.2 |
Umbraco.Community.Templates.PackageStarter |
17.1.1 |
17.1.1 (already v17) |
TestSite Umbraco.Cms
|
17.5.3 (bumped from template's 17.0.0) |
— |
Clean |
7.0.8 |
8.0.1 → Umbraco 18 |
Umbraco.AI |
17.1.1 |
18.1.1 |
Umbraco.AI.Prompt |
17.1.0 |
18.1.0 |
Umbraco.AI.Agent |
17.1.0 |
18.1.0 |
Umbraco.AI.Agent.Copilot |
17.0.0 (stable) |
18.0.1 |
Umbraco.AI.Amazon / .Anthropic / .Google / .MicrosoftFoundry
|
17.0.0 |
18.0.0 |
Umbraco.AI.OpenAI |
17.1.0 |
18.1.0 |
package project Directory.Packages.props (Umbraco.Cms.*) |
17.5.3 |
18.x |
@umbraco-cms/backoffice (Client) |
^17.5.3 |
^18.x |
What's next
Because the templates now scaffold the package project against 17.5.3 (not 17.0.0), you can skip the original post's "bump the four Umbraco.Cms references to 17.1.0" step -- you're already above the Umbraco.AI.Core floor of 17.1.0. When you start on package code:
dotnet add src/AI.Woowoo package Umbraco.AI.Core -v 17.1.1
Install the Umbraco Backoffice Skills for your AI coder
/plugin marketplace add umbraco/Umbraco-CMS-Backoffice-Skills
/plugin install umbraco-cms-backoffice-skills@umbraco-backoffice-marketplace
/plugin install umbraco-cms-backoffice-testing-skills@umbraco-backoffice-marketplace
Top comments (1)
Tip:
After installing all the AI packages and the Clean starter kit, make sure to enable ModelsBuilder, with SourceCodeManual in appsettings.json
And then, before stopping the site, go to the Models Builder dashboard in the Settings section, and generate the models.
If not, the site can't build the next time you run it, as the razor views in the starter kit expects the models to be there :)