General

Umbraco 18 Finally gives reusable content the home it deserves

There are flashy features that get everyone excited—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, "Here we go. This is definitely going to be one of my favorite updates since a long time." It's not a brand-new idea. In fact, it's almost more impressive because it turns something most experienced Umbraco developers have hacked together themselves into an actual, official feature.

If you’ve built Umbraco websites for any length of time, you’ve probably done this: made a “Globals “ of “Various Content” 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… most of the time. But let's be honest—it always felt like a kludge.

That kind of content never really belonged alongside website pages. This “content” didn’t need URLs; users weren’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.

The missing piece

Reusable content isn't some fringe requirement. Nearly every site needs it. Think about all those bits that pop up on several pages: contact cards, office locations, opening hours, author profiles, promotional banners, call-to-action blocks, testimonials, product highlights, event speakers, and FAQ entries.

Traditionally, you had two choices. First, copy the content all over the place—which is no one’s idea of fun. If Marketing tweaks the wording, someone's clicking through twenty pages making the same change again and again.

The other pattern? Hide a page in the Content tree somewhere, and reference it whenever needed. That's what most of us ended up doing. Sure, this cut down the duplication, but it had a cost. The Content tree morphed into a mess where some nodes were genuine pages and the rest were just data containers.

From a developer’s perspective, not ideal. For editors, this was just confusing.

Enter the Library

Umbraco 18 introduces the Library. A new area in the CMS that gives reusable content its own home. Reusable blocks no longer sit inside the structure of your actual website. The Library gives them a clear, dedicated place.

That might sound like a minor distinction, but it changes how editors and teams understand their content. Pages live in Content. Reusable parts live in the Library. Suddenly, everything makes sense. No more explaining that “this isn’t really a page” — the CMS itself shows that separation. That's the magic. It's not just cleaner, technically; it's simpler, conceptually.

Meet Elements

So, what’s actually in the Library? Elements. If you’ve used Block List or Block Grid editors before, this won't sound new. Element Types have been around for a while. The big jump is that now, Elements can live as first-class content in the Library. They have their own lifecycle, can be published, support permissions, are versioned, and can be rolled back. They're reference tracked, just like any other normal content—but without a route. That's exactly right. A call-to-action for the whole company shouldn't pose as a webpage. An author profile doesn't need a URL. An office location shouldn't get shoved under “Globals”. These are content, but they’re not navigable. The Library finally acknowledges that.

Creating your first reusable element

It's surprisingly simple to start. Let’s say you want a reusable Call To Action component. Start with an Element Type—like you always would. Add your properties: heading, intro, button text, button link, background color. The key difference is the new checkbox: Allow in Library. That one checkbox is the whole game. Once ticked, editors can create real instances of that Element in the Library. No more hidden CTA pages in Content but just clean entries in Library.

I’ve asked around with our own internal editors and they “get” this right away. It’s obviously not some stealth page, it’s specifically for reuse.

One source of truth

Imagine a marketing campaign spread across fifty landing pages. Each page has the same promotional banner with a whitepaper download link. Before reusable Elements, you’d either double up the content fifty times or use a hidden page. Neither solution is slick.

With the Library, you have one banner Element. All pages reference it. So if Marketing wants to change text, button color, or a link, the editor updates the Element once and republishes. Instantly, all pages show the new version. No more duplicates. No forgotten pages. No inconsistencies. Editors love this. Developers love this.

Let's move from the ideas to the code—let’s see how to hook this up with ModelsBuilder, configure the new Element Picker, and just how little code’s involved when you want reusable content in templates.

Building with Elements: From Content Model to Razor

Now that we know why the Library exists, let’s build with it. The nice part: there’s no new API to learn. If you’re comfortable with Umbraco, you’ll find this easy. That’s a sign of a good feature—it fixes a problem without making you relearn Umbraco.

For this, let's set up a reusable Call to Action for blog posts, landing pages, and product pages. Editors manage it once—done.

Step 1: Create an Element Type

Make a new Element Type, Call To Action. Add the properties you want. The important thing: enable Allow in Library. Without that, the Element works like it always has, inside Block editors only. With the box checked, it also shows up in the Library, so editors can create as many reusable CTAs as they need.

I really like this: instead of inventing a new content model, Umbraco extends one everyone already understands.

Step 2: Create Your Library Items

Jump over to Library. Make a “Marketing” folder. Inside, create your reusable CTAs: Download our Whitepaper, Book a Demo, Contact our Experts, Subscribe to our Newsletter. Editors find this structure natural. Instead of, “Where’s that hidden CTA page?” you just look in Library.

Sometimes, the simplest UX shift is the most powerful.

Using the Element Picker

Next, expose these Elements to editors. Suppose you have a Blog Post Document Type. No need for a Block List or a Content Picker tied to some hidden location—just add an Element Picker property. Name it featuredCallToAction. Now, editors just browse the Library and grab any of the reusable CTAs.

No duplicate content. No hidden content. No tricky trees. Just a neat picker of reusable Elements. This is exactly what I wanted when I saw it previewed at Codegarden.

ModelsBuilder Makes This Even Better

Enable ModelsBuilder; it makes everything easier. Strongly typed models are easier to read, safer to refactor, and less error-prone. Instead of: var heading = Model.Value<string>("heading"); you just do Model.Heading. Tiny change, huge long-term difference. IntelliSense and compile-time checking will save you headaches.

Imagine ModelsBuilder generates something like:

public partial class CallToAction : PublishedElementModel {
    public string Heading => this.Value<string>("heading");
    public string Text => this.Value<string>("text");
    public Link ButtonLink => this.Value<Link>("buttonLink");
    public string ButtonText => this.Value<string>("buttonText");
    public string BackgroundColor => this.Value<string>("backgroundColor");
}

You don’t edit this code, but knowing what’s going on helps you design and debug your implementation.

Rendering the Element

Rendering is really straightforward. Your page model might look like this:

@if (Model.FeaturedCallToAction is not null) {
    <partial name="Partials/CallToAction" model="Model.FeaturedCallToAction" />
}

That's it. The page doesn’t care where the CTA lives—it just gets the Element.

Building a Reusable Partial View

Your partial is clean and simple:

@inherits UmbracoViewPage<CallToAction>
<section class="cta" style="background:@Model.BackgroundColor">
    <h2>@Model.Heading</h2>
    <p>@Model.Text</p>
    @if (Model.ButtonLink is not null) {
        <a href="@Model.ButtonLink.Url" class="btn">@Model.ButtonText</a>
    }
</section>

No more Value() calls, no string aliases, just strongly typed data. Personally, this is way easier to maintain.

Multiple pages, One Element

Picture this: homepage, product page, blog article—all use the same CTA. Maybe it’s “Download Whitepaper.” Marketing wants it to say “Start Your Free Trial” instead of “Download Now.” Old way, someone’s editing a pile of pages. With Elements, you update it in one spot, publish, done. All referencing pages show the latest version, instantly. That’s a workflow editors will notice immediately.

Avoiding Duplicate Partials

One more best practice: one partial view per Element Type. Like so:

/Views/Partials/Elements/
    CallToAction.cshtml
    Testimonial.cshtml
    Author.cshtml
    OfficeLocation.cshtml
    TeamMember.cshtml

Very quickly, your project starts to look like a proper component library. Every reusable Element gets its model, its partial, and its rendering strategy. It’s predictable, maintainable, and easy for new developers to jump in.

What About Dependency Injection?

Sometimes Elements need extra info when rendering—say, a CTA needs campaign tracking, or office locations need current hours, or a product teaser pulls pricing from another system. Don’t dump this logic into Razor. Use a dedicated service and inject what you need. This keeps Elements focused on content, not business rules. The Library just encourages these clean boundaries even more.

Migrating from "Globals" to the Library

If you’ve been with Umbraco for a bit, you might ask, “Great, but what about our existing setups?” Most mature Umbraco installs already have some method—a Globals node, Settings, Shared Content, whatever—for reusable content. Usually it’s a hidden place in Content for stuff that’s not really a page.

Good news: you don’t have to migrate all at once. Actually, it’s probably smarter not to. So don’t Migrate Everything At Once

I’ve seen big teams use new features as a reason to rebuild everything. But just because the Library is available doesn’t mean you should move every reusable bit right now. Ask yourself: does this content have its own URL? Should users navigate to it? Is it referenced in multiple places? Does it represent reusable info instead of a page? If “yes,” it probably belongs in the Library as an Element. If it’s an actual page (even if only occasionally visited), leave it.

Your goal isn’t moving all content, it’s to model content accurately.

A migration strategy that works

If I was planning migration for a client, I’d go step by step:

Phase 1:
Leave everything as it is. No rush. The current setup works just like before.

Phase 2:
Introduce the Library. For anything new (promotional banners, CTAs, author profiles, contact cards), start using the Library. Old stuff stays where it is.

Phase 3:
Replace content naturally. As editors update parts of the site, migrate them over. For example, if Marketing refreshes the newsletter signup, create it as an Element instead of updating the old node. Each deployment chips away at technical debt with no dramatic rewrites.

I like this because it follows my favorite software rule: leave the codebase a little better than you found it. Gradual improvements last much longer than big-bang rewrites.

Where Elements really shine

After tinkering with Elements for a while, I've noticed a few scenarios where they’re an easy win:

  • Author profiles:
    Blogs with multiple authors can reference a single Author Element for bios, titles, pictures, and links. New photo? Promotion? Update it once and every reference is current.

  • Office locations:
    Multi-office companies often repeat addresses. Library Elements eliminate this; each office details live in one place.

  • Testimonials:
    Marketing likes to scatter the same quotes everywhere. Single Elements mean no duplication.

  • Campaign components:
    Build an entire campaign from modular Elements—hero banner, CTA, ribbon, download block, event registration, speaker profile.

Reusable, modular, maintainable - all things a modern CMS should encourage.

Best practices I’m already using

Umbraco 18 is new, but I’ve already built some habits I’ll keep using:

  • Keep Elements focused
    Don’t cram dozens of properties into one. Treat them like UI components. One responsibility, one purpose. If an Element feels confusing, split it up.

  • Name them clearly
    Editors think in business language, not in code. Use straightforward names; Newsletter Signup, Customer Testimonial, Office Location, Event Speaker.

  • Organize the Library
    A handful of Elements? Fine. Hundreds? Not so much. Use folders like Marketing, Editorial, Legal, Company, Products, Events to keep things tidy. Just like Media folders.

  • No business logic in Razor
    This goes for all Umbraco templates. Use services for logic, rendering for layout.

Performance considerations

I was thinking: do referenced Elements add overhead? In practice, not for most sites. The published cache already does tons of work, and Elements integrate like regular published content. The architectural wins (cleaner models, less duplication, better workflows) far outweigh any small performance concerns. Measure first, optimize second.

Looking ahead

At Codegarden, it was obvious the Library is just a starting point. This isn’t a one-off. It's a foundation for richer features—block editor integration, better relationships between Elements, improved governance, and more sophisticated enterprise tools. Honestly, I wouldn’t be surprised if, a few major versions out, we look back and see Umbraco 18 as the release where reusable content finally went mainstream.

For years, we rolled our own solutions—hidden nodes, Content Picker hacks, homebrew conventions. Now, we don't have to. Umbraco finally offers a place for reusable content, and it feels like it's always belonged there. That’s the best thing I can say about any new feature. It’s intuitive. It’s clean. It just makes the CMS easier!