Multi-site Umbraco without the shared tree mess
CMS

Multi-Site Umbraco without the shared-tree mess

At some point in a multi-site Umbraco project, someone creates a "Global" or "Shared" content node to hold whatever multiple sites need in common, and it never stops growing. Six months later it's holding navigation overrides, campaign banners some sites don't use, and properties nobody remembers the purpose of. This isn't really a technical failure, it's what happens when a single-site content model gets stretched across multiple sites without anyone deciding what "shared" actually means. Getting the structure right from the start, across content, media, permissions and search, keeps the tree something editors can still read a year later.

The Global Folder nobody wants to touch

At some point in a multi-site Umbraco project, someone creates a content node called "Global" or "Shared" or "Settings" at the root of the tree. It starts innocently. Maybe it holds a footer text block that's the same across two brands, or a set of social links every site needs. Six months later it's holding navigation overrides, campaign banners three sites reference but one doesn't, a "temporary" redirect list, and at least one property nobody remembers the purpose of.

This is the shared-tree mess, and if you've built more than one multi-site Umbraco install, you've seen a version of it. It's not really a technical failure. It's what happens when a single-site content model gets stretched across multiple sites without anyone deciding, upfront, what "shared" actually means.

Why one install ends up running several sites

There are two common routes into a multi-site setup. An agency hosts several clients' brands in one Umbraco instance to save on infrastructure and maintenance overhead. Or a single organisation runs regional or brand variants of the same site, sometimes with different domains, sometimes with different content per language.

Umbraco supports this reasonably well at the structural level. You add another root content node, give it its own document type or reuse existing ones, and assign a domain to it through the culture and hostnames settings on that node. Requests get routed to the right root based on the incoming hostname, and from the editor's point of view each root behaves like its own site.

The trouble starts once two sites need to share something. A footer. A cookie banner. A set of office locations. A CTA block that marketing wants consistent across every property. That's the moment teams reach for the Global folder, because it's the fastest way to make one node visible from every tree, and nobody stops to ask what the alternative actually costs.

Multi-Site is not Multilingual, Even though they look similar

Before going further, it's worth separating two problems that often get solved with the same folder structure and shouldn't be.

A multilingual site is one site with variant content per culture, using Umbraco's language variance on properties and document types. A multi-site install is genuinely separate sites, each with their own domain, navigation and often their own content model, that happen to live in one Umbraco instance.

Teams sometimes model a multi-brand setup as if it were multilingual, variance turned on across the board, one root node, culture-specific values on every property, because two brands share 80% of their content and it feels wasteful to duplicate the tree. This tends to work until the two brands diverge on structure rather than just wording. A property that exists for Brand A but makes no sense for Brand B, a page type Brand A needs and Brand B doesn't, a navigation depth that differs between the two. At that point you're fighting variance to express structural differences it was never meant to carry, and every editor has to understand which properties are actually culture-variant versus which ones happen to render differently per brand for other reasons.

If the sites are genuinely different products with different domains, model them as separate roots from the start, even if today's content looks nearly identical. If they're the same product in different languages, use variance and keep them under one root. Mixing the two approaches because it's less setup work now is one of the more expensive shortcuts to walk back later.

Where the mess actually comes from

The Global folder pattern has a few recurring problems, and they compound as you add sites.

Permission scope gets blurry. Umbraco's content permissions are typically set per start node. If your shared content lives in one Global node that every editor across every site can reach, you either give everyone access to everything, or you carve out permissions so awkwardly that editors stop trusting the tree.

The tree stops describing the sites. A content tree is supposed to be a mental map for editors. Once it contains a mix of real pages and quietly-referenced data nodes, editors lose the ability to look at the tree and know what's actually a page on the website. This is the exact problem the Library and Elements feature in Umbraco 18 was built to solve, and if you're on a version that has it, shared campaign components, office locations and author profiles belong there rather than in a hidden node under Content. If you're not on 18 yet, the same principle still applies: keep site-specific pages and cross-site reusable data structurally separate, even if that separation is just discipline and folder naming rather than a dedicated feature.

Relations reach across sites in ways deployments don't expect. A Content Picker property doesn't care which root its target lives under. That's fine until you need to delete or restructure one site and discover another site has a live dependency on a node three levels deep in it. These references are invisible until something breaks.

Document types drift. Two sites that started identical rarely stay that way. A property added for Site A "just this once" ends up on a shared document type used by Site B, where it means nothing and confuses whoever inherits the project.

A structure that scales past two sites

The fix isn't a clever feature. It's being explicit, from the start, about which of three categories a piece of content actually falls into.

Site-specific content lives entirely under its own root, with its own document types where the content genuinely differs between sites. Don't force two sites onto one document type just because they look similar today.

Identical shared content is the same everywhere and rarely edited per site: a CTA library, an author roster spanning brands, standard legal boilerplate. This is exactly what belongs in the Library as Elements if you're on 18, referenced from each site via an Element Picker rather than copied or reached for with a cross-tree Content Picker. If you're on an earlier version, the closest equivalent is a dedicated, clearly named root node (not buried under Content) with restricted edit permissions, treated as configuration rather than as pages.

Per-site variants of shared concepts are the case teams get wrong most often. A footer that's structurally identical but has different links per site isn't shared content, it's a settings document type that exists once under each site root. Resist the urge to centralise something just because it looks the same on every site today. Two sites needing the same links right now doesn't mean they'll need the same links next year, and untangling a false shared dependency later is far more expensive than duplicating a settings node up front.

A structure that tends to hold up looks roughly like this:

Content
├── Site A
│   ├── Home
│   ├── Settings (footer, nav overrides, site-specific config)
│   └── ... pages
├── Site B
│   ├── Home
│   ├── Settings
│   └── ... pages
Library
├── Marketing
│   └── shared CTAs, banners
├── Company
│   └── shared author profiles, office locations

Nothing here is exotic. The value is entirely in the discipline of keeping "this site's pages," "this site's per-site config," and "genuinely shared, centrally managed content" in three visibly different places instead of one folder that tries to be all three.

Media is a separate decision

Media libraries in a multi-site install create the same question as content: shared or per-site. Most projects default to one shared media library because it's the path of least resistance, and for genuinely shared assets (a company logo, a shared icon set) that's fine. Where it goes wrong is when marketing assets for one brand start appearing in another site's image picker because nobody scoped the media picker to a folder.

A simple convention, one top-level media folder per site plus a "Shared" folder for assets used everywhere, combined with start-node restrictions on media pickers where it matters, avoids most of the confusion without needing anything clever.

Search needs the same boundaries as everything else

If a multi-site install includes on-site search, it's easy to forget that Examine, by default, indexes the whole content tree, not one site's slice of it. Ship that without adjustment and Site A's search box will happily return results from Site B, including pages a visitor has no way to navigate to and content editors never intended to expose outside their own domain.

The fix is the same discipline applied elsewhere in this article: decide per site whether search needs its own index or a shared index filtered by a site identifier, and build that into the index configuration rather than trying to filter it out ad hoc in the query. A value set at content creation time, whether that's the root node ID, a domain-derived key, or an explicit site field on the root, gives you something reliable to filter or facet on. Retrofitting this after search has been live for a year, once external links and bookmarks assume the current behaviour, is a much less pleasant conversation with a client than raising it during initial setup.

The same logic applies to the Content Delivery API if the project is headless. A consuming frontend for Site A should not be able to pull content belonging to Site B just because both live in the same Umbraco instance. Scoping delivery API requests to a site, whether through separate API keys, a root-based filter, or a dedicated endpoint per site, is worth deciding before the first frontend integration ships rather than after a consumer discovers it can see more than it should.

Permissions are part of the architecture, not an afterthought

User groups in Umbraco can be restricted to a content start node, and in a multi-site install this is one of the more underused tools. Editors for Site A generally shouldn't be able to browse into Site B's tree, and definitely shouldn't have write access to shared Library content unless that's genuinely part of their job. Deciding this at the same time you design the content structure, rather than retrofitting it once an editor accidentally republishes another brand's homepage, saves a very awkward conversation later.

Untangling an existing global folder

Most Umbraco developers aren't setting up a multi-site install from scratch. They're inheriting one, Global folder and all, and being asked to add a third site to it. Rewriting the whole structure in one go is rarely realistic, and it isn't necessary.

A more workable approach is to stop the bleeding before trying to clean up the past. Freeze the existing Global folder: no new content types get added to it, and any new shared requirement goes into a proper Library Element or a clearly named, permission-restricted node instead. Then work through what's already in Global and sort it into the three categories from earlier. Content that turns out to be genuinely site-specific, despite living in a shared node, gets moved back under its own site root. Content that's genuinely shared gets migrated into the Library or a dedicated settings structure, one item at a time, as pages that reference it get touched anyway for other work.

This is slower than a big rewrite, but it doesn't require a dedicated migration sprint that's hard to justify to a client who isn't seeing a new feature out of it. It also avoids the classic failure mode of "let's fix the whole content tree" projects, where half the site ends up migrated and half doesn't, leaving two competing patterns for the next developer to figure out.

When one install is the wrong answer

None of this fixes the deeper trade-off of running multiple sites from a single Umbraco instance: they share a codebase, a deployment pipeline and an upgrade cycle. A breaking package update or a major version upgrade affects every site at once, whether or not all of them need it. A custom document type change for Site A can require a full deploy that touches Site B's uptime too.

For a handful of closely related sites under one team's control, that's usually an acceptable cost, and the shared infrastructure is a real saving. Once sites start belonging to genuinely different teams, need independent release schedules, or have wildly different traffic and performance profiles, separate installs (sharing packages and conventions rather than a database and a content tree) tend to be less trouble than trying to keep one install polite to everyone using it.

The actual rule

The shared-tree mess isn't caused by multi-site Umbraco being hard. It's caused by treating "shared" as one category when it's really three: site-specific, genuinely shared, and coincidentally similar. Get that distinction right before the second site goes live, and the content tree stays something editors can read at a glance. Get it wrong, and you spend the next two years explaining to new team members why half of Site A's homepage is actually configured somewhere under Site C.