Upgrading from Umbraco 13 (LTS) to Umbraco 17 (LTS) is not a simple version bump. It is a upgrade that affects your framework, dependencies, search layer, and often a significant amount of custom code.

Over time, I have settled on a phased approach that combines early validation, incremental upgrades, and a strong focus on getting the website running as soon as possible. This article describes that approach and how I typically apply it in real projects.

The goal is to stay in control while moving forward steadily.

Phase 0: Analysis and Decisions

Before touching any code, I start with analysis.

First, I check which community packages support Umbraco 17. Unsupported packages are an early risk indicator and often require replacement or removal.

Next, I review all custom packages in the solution and ask a few critical questions:

  • Can this be replaced by a community alternative?

  • Does it still add real value?

  • Does it need to be rebuilt for Umbraco 17?

This phase sets expectations early. Decisions made here directly influence how smooth the rest of the upgrade will be.

I strongly recommend involving your customer at this stage. An upgrade is a good moment to remove logic that is no longer needed or to replace custom solutions with more maintainable alternatives.

Phase 1: Database-First Validation with a Temporary Umbraco 17 Site

Before upgrading the real solution, I first validate the database.

I create a temporary Umbraco 17 project and:

  • Restore a local copy of the database and media

  • Connect the temporary project to that data

  • Let Umbraco upgrade the database schema

  • Install the required community packages

  • Generate models using ModelsBuilder

This phase answers critical questions early:

  • Does the database upgrade succeed?

  • Do packages migrate correctly?

  • Are content types and properties still valid?

It is important to keep in mind that custom property editors will not work at this stage. That is expected and not a blocker. The goal here is validation, not completeness.

At the end of this phase, I have a clean Umbraco 17 database and a set of generated models that represent the upgraded schema. This provides a solid and reliable starting point for the rest of the upgrade.ent the upgraded schema and should have a good starting point.

Phase 2: Upgrade Core Projects, Business Logic, and Search Foundations

Now the real solution upgrade begins.

I update the solution project by project, starting with the smallest projects that have the fewest dependencies. A typical order looks like this:

  • Core projects

  • Data and domain projects

  • Business logic

  • Search foundations and indexing logic

For each project, I:

  • Upgrade to .NET 10

  • Update Umbraco packages to version 17

  • Resolve deprecated APIs

  • Fix compilation errors

For the data project, where the generated models usually live, I copy the models from the temporary Umbraco 17 project into the real solution. This removes a large number of content-related compile errors early and allows dependent projects to compile much faster.

Search is explicitly included at this stage. Indexers, value extraction, and event-based indexing logic are upgraded early, so the website does not fail later due to missing or broken search dependencies.

At this point, I deliberately exclude backoffice-specific logic where necessary. The backoffice is typically the area most affected by breaking changes between Umbraco 13 and 17. Temporarily excluding this logic helps keep focus on getting the core and frontend foundations compiling first.

The goal of this phase is a stable, compiling foundation, including all search-related code, on top of which the rest of the solution can be safely upgraded.

Phase 3: Custom Property Editors and Model Regeneration

With the core logic in place, I focus on custom property editors.

At this point:

  • I replace custom editors with community alternatives where possible

  • Only rebuild editors if no suitable alternative exists

  • Remove obsolete or unused editors entirely

Once property editors are fixed, I regenerate the models again.
This step is important.

Property editors directly influence generated models and value converters. Regenerating ensures:

  • Models reflect the final editor setup

  • Data and website projects compile against the correct schema

  • Hidden editor-related issues surface early

Skipping this step often leads to subtle runtime bugs later.

Phase 4: Controllers, ViewComponents, and Search Integration

With the solution compiling, I start validating runtime logic.

In this phase:

  • Controllers are updated according to Umbraco 17 documentation

  • ViewComponents are reviewed and validated

  • New Umbraco services are introduced where older APIs no longer exist

  • Missing notifications or removed hooks are skipped instead of reimplemented immediately

Search is validated end-to-end:

  • Indexing runs

  • Queries execute

  • Results are returned correctly

This phase ensures the frontend logic behaves correctly on Umbraco 17.

Phase 5: Run the Website and Perform a Visual Check

At this point, I run the website.

This is a short but important checkpoint:

  • Does the site start?

  • Can pages be rendered?

  • Is the layout roughly correct?

If the website works visually and functionally at a basic level, I proceed with confidence.

Phase 6: Backoffice Logic and Integrations

Before refining the frontend, I focus on the backoffice.

This includes:

  • Backoffice customizations

  • Synchronization logic

  • API integrations

  • Middleware

  • Notifications and background processes

If a backoffice issue appears at any point, it takes priority over frontend issues. Editors must be able to work reliably before anything else matters.

Phase 7: Replace Obsolete Code and Execute a Structured Test Period

Only after the platform is stable do I return to obsolete code.

In this phase:

  • Obsolete APIs are replaced with correct Umbraco 17 alternatives

  • Architecture is aligned with modern Umbraco patterns

Testing is structured and deliberate:

  1. Backoffice first

    • Content editing

    • Publishing

    • Media handling

    • Custom dashboards and workflows

    • Notifications

  2. Frontend second

    • Page rendering

    • Navigation

    • Forms

    • Search behavior

If a backoffice issue is found during testing, it is always fixed first. A visually perfect website is useless if editors cannot work.

Common Pitfalls During an Umbraco 13 to 17 Upgrade

Some issues I regularly see during upgrades:

  • Upgrading the website project before core and data projects

  • Leaving unsupported community packages in place “temporarily”

  • Delaying search upgrades until the end

  • Forgetting to regenerate models after fixing property editors

  • Spending too much time fixing frontend issues before the backoffice is stable

Avoiding these pitfalls saves time and frustration later.

Final Steps and Global Guideline

This approach is intentionally generic. It is not tied to a single project, setup, or client. The same principles apply whether you are upgrading a small site or a large multi-project solution.

Key principles:

  • Validate the database early

  • Upgrade bottom-up

  • Include search early

  • Fix property editors before regenerating models

  • Prioritize compilability over completeness

  • Treat backoffice stability as the highest priority

  • Replace obsolete code only after the platform is stable

An Umbraco 13 to 17 upgrade does not need to be chaotic. When approached in structured phases, it becomes predictable, repeatable, and manageable across projects.

I use this approach as a baseline for every Umbraco LTS upgrade and adapt it per project where needed.