How Phases migrated a large public-sector Umbraco platform with hundreds of legacy content components, custom code, search and Salesforce integrations while keeping the public website available.
NYC Votes serves more than 5.5 million New York City voters, publishes content across 14 languages, and depends on Umbraco alongside several external systems.
Moving it from Umbraco 8 to Umbraco 13 therefore involved much more than changing the CMS version.
Hundreds of Grid and Nested Content components had to be migrated. Existing custom code had been written for the older Umbraco architecture. Custom indexing and Salesforce integrations needed to work after the change.
Phases used a direct migration approach, including uSyncMigrations, to bring the content into the newer Umbraco structure while the wider application was rebuilt and validated around it.
The upgrade at a glance
|
Project |
NYC Votes |
|
Sector |
Public sector / civic technology |
|
Umbraco upgrade |
Umbraco 8 → Umbraco 13 |
|
Audience |
5.5M+ New York City voters |
|
Languages |
14 |
|
Legacy content |
Hundreds of Grid and Nested Content components |
|
Content migration |
Grid → Block Grid, Nested Content → Block List |
|
Migration tooling |
uSyncMigrations |
|
Custom development |
Reviewed, refactored and rebuilt for the newer architecture |
|
Integrations |
Salesforce, election data services and location services |
|
Search |
Custom indexing updated and validated |
|
Infrastructure |
Microsoft Azure |
|
Release setup |
Development, QA, UAT and Production with CI/CD |
|
Public availability |
Maintained during the upgrade |
The wider NYC Votes platform supports 14 languages and has achieved a 100% WCAG 2.2 accessibility audit score.
Those figures are important, but they were not the difficult part of the upgrade.
The difficult part was changing the technology underneath an established public service without losing what already depended on it.
Why NYC Votes needed an Umbraco upgrade
The platform was running on Umbraco 8.
The upgrade was required to address security patch requirements, improve performance and improve the maintainability of the existing codebase.
But Umbraco 8 to 13 is not comparable to applying a routine minor-version update.
Umbraco 8 applications were built around an older MVC and .NET Framework architecture. Umbraco 13 belongs to the newer ASP.NET Core and .NET generation.
That architectural change meant the team had to consider the content and the application separately.
Content needed a reliable migration route.
Custom code needed to be reviewed against the new architecture.
Search needed to be updated.
Integrations needed to be tested.
And the public service still needed to work when the new implementation was released.
For an organisation considering an Umbraco upgrade, this is an important distinction.
The number of versions between the starting point and destination tells only part of the story. The larger question is how much business logic, content and connected software has accumulated around the CMS.
The content challenge: hundreds of legacy components
NYC Votes used hundreds of Grid and Nested Content components.
Both were established ways of building structured content in older Umbraco implementations, but modern Umbraco uses its Block editors instead.
The upgrade therefore required two significant content transformations:
Grid → Block Grid
Nested Content → Block List
Rebuilding that content manually would have meant recreating a substantial amount of existing structured content.
Instead, Phases used uSyncMigrations as part of the migration.
uSyncMigrations supports transformations between legacy and newer Umbraco property editors, including Grid to Block Grid and Nested Content to Block List.
For NYC Votes, this gave the team a more controlled way to bring existing content into the modern content model while preserving the structure the website already depended upon.
The purpose was not simply to copy database records.
The migrated content still had to make sense to editors and render correctly within the new implementation.
The application also had to be rebuilt around modern .NET
Moving the content did not complete the upgrade.
Custom functionality written for Umbraco 8 had to be assessed against the newer Umbraco and .NET architecture.
Existing custom code was reviewed and, where necessary, refactored or rebuilt.
This is an area that can materially change the size of an Umbraco migration.
Two websites might both be running Umbraco 8, but one may consist largely of standard CMS functionality while another contains years of application logic, custom property editors, integrations, search behaviour and bespoke backoffice functionality.
The second project is not simply a larger version of the first.
It requires architectural work.
For NYC Votes, that included the code surrounding the CMS as well as the CMS itself.
Custom indexing needed its own upgrade work
Search and indexing were another part of the migration.
NYC Votes contained custom indexing, which meant the implementation needed to be reviewed and updated for compatibility with the new platform.
This can easily be missed when an upgrade is scoped only around pages and templates.
Search behaviour often depends on custom fields, indexing rules, filtering logic and external data. If those relationships change during an upgrade, the website may technically be running while an important part of the user experience no longer behaves as expected.
The indexing work was therefore treated as part of the application migration rather than something to check after launch.
Salesforce and other integrations had to survive the change
NYC Votes is connected to systems outside Umbraco.
Forms integrate with Salesforce, while election information and location-based experiences rely on external services.
Those connections had to continue working when the CMS architecture changed.
The Salesforce implementation therefore required updates and compatibility validation as part of the upgrade.
For another organisation, the systems may be different: Dynamics, an ERP, identity platform, product database, payment provider, search service, membership system or a bespoke API.
The principle is the same.
An Umbraco upgrade should account for what enters the CMS, what leaves it and which organisational processes depend on those exchanges.
A website can load correctly and still have an unsuccessful upgrade if the processes behind it have stopped working.
Keeping NYC Votes available while the platform changed
NYC Votes could not simply disappear while a new implementation was prepared.
The platform serves a large public audience and continues to change around election cycles.
The development process therefore used separate development, QA, UAT and production environments, with changes managed through version control and CI/CD.
This allowed the upgraded implementation to be developed and validated away from the live public service before release.
Public access continued during the upgrade.
For a CTO, CIO or digital team responsible for an established platform, this is often more useful than knowing only which migration tool was used.
The upgrade plan has to include how the existing service continues operating, how the new implementation is tested, and how the organisation reaches production without treating its users as the testing environment.
What changed after the upgrade
The NYC Votes upgrade moved the platform from Umbraco 8 to the newer Umbraco and .NET architecture while retaining the content and connected functionality the service depended upon.
The work included:
-
migrating hundreds of legacy Grid and Nested Content components
-
moving Grid content into Block Grid
-
moving Nested Content into Block List
-
refactoring or rebuilding custom application code
-
updating custom indexing
-
updating and validating Salesforce integration
-
preserving the wider content structure
-
maintaining public access through the migration
-
establishing a more maintainable technical base for continued development
The development team also recorded improved website performance, improved security and a more maintainable codebase following the upgrade.
We do not currently have a verified percentage that we can responsibly attach to the performance improvement, so we would rather state the outcome than invent a benchmark.
Why this case is useful beyond NYC Votes
The most useful lesson from this project is not simply that Phases has upgraded an Umbraco 8 website.
It is what sat inside that website.
A large content structure.
Hundreds of legacy components.
Custom .NET code.
Custom indexing.
CRM integration.
External data.
Multiple languages.
Azure infrastructure.
An active release process.
And millions of people relying on the public service around it.
That combination is much closer to the situation many enterprise and public-sector teams face when an older Umbraco implementation reaches the point where it needs to be modernised.
The CMS may be only one layer of the system.
A sensible upgrade plan starts by understanding everything attached to it.
Should you upgrade to Umbraco 13 now?
No.
NYC Votes was upgraded to Umbraco 13 when that version was an appropriate destination for the project.
The platform lifecycle has since progressed.
Umbraco 13 reaches End of Life on 14 December 2026. After that date, it will no longer receive the normal security patches and technical support supplied by Umbraco HQ.
For organisations beginning an upgrade now, Umbraco 17 LTS is one of the current supported destinations to assess.
Umbraco 17 was released on 27 November 2025 and its published lifecycle runs until 27 November 2028.
The value of the NYC Votes project today is therefore not the destination version.
It is evidence of how Phases approaches the difficult part of an upgrade: moving content, custom software and integrations across major Umbraco generations without treating the CMS as an isolated application.
What would we assess on another Umbraco upgrade?
Before recommending an upgrade route, we would normally want to understand:
-
current Umbraco and .NET versions
-
installed packages and whether supported replacements exist
-
Grid, Nested Content and other legacy property editors
-
custom backoffice functionality
-
bespoke application code
-
search and indexing
-
APIs and third-party integrations
-
authentication and permissions
-
forms and CRM flows
-
content volume and structure
-
hosting and deployment
-
test coverage
-
editor requirements
-
accessibility requirements
-
production release and rollback approach
That assessment is what turns “we need to upgrade Umbraco” into a project that can be scoped properly.
Running Umbraco 13?
If you are currently running Umbraco 7, 8, 10 or 13, we can review the existing implementation before you commit to a migration route.
That means looking at the CMS version alongside the packages, content models, custom code, integrations, search, infrastructure and release setup already around it.
You should come away knowing what can be migrated, what needs rebuilding, what needs testing and what the likely path to a supported Umbraco version looks like.
-
Can an Umbraco 8 website simply be updated to a modern Umbraco version?
The migration route depends on the implementation. Umbraco 8 sits on an older application architecture, so content migration and application migration need to be assessed separately. Legacy packages, custom code and property editors can materially affect the route.
-
How can Grid content be migrated to Block Grid?
Migration tooling such as uSyncMigrations can convert legacy Grid content into modern Block Grid structures. NYC Votes used this approach as part of migrating hundreds of Grid and Nested Content components.
-
Can Nested Content be migrated to Block List?
Yes. uSyncMigrations supports migration from Nested Content to Block List. The resulting implementation should still be validated against the content model, templates and editor experience required by the website.
-
Does custom code need to be rewritten when moving from Umbraco 8?
Often, yes. Umbraco 8 and modern Umbraco versions use different underlying .NET architectures. Existing application code, packages and backoffice customisations should therefore be reviewed rather than assumed to work unchanged.
-
Can integrations remain in place during an Umbraco upgrade?
They can, but compatibility needs to be tested. On NYC Votes, Salesforce and other connected services formed part of the upgrade work rather than being treated as separate systems that would automatically continue working.
-
Which Umbraco version should we upgrade to in 2026?
The answer depends on the requirements and timing of the project. Umbraco 13 reaches End of Life on 14 December 2026. Umbraco 17 is the current LTS release and has a published EOL date of 27 November 2028. The existing implementation should be assessed before deciding the destination version.