Adding an Angular app to your Umbraco Website

What problems does this solve?

  • This enables you to have an Angular application alongside your Umbraco website, on a specified route.
  • The Angular App can be protected by the Authentication of your website, if you have it. And you can make use of surface controllers for authenticated requests.
  • The routing of your app will work as intended, for example, if your Angular app is at /app and you make a request to /app/products, the request will be routed to the angular app products’ page.

What this is not

  • A complete front end for a Umbraco website with dynamic routes.
  • This doesn’t have dynamic routes, you have to specify them on your code.

Let’s get started!

First, start by creating a controller to handle the Angular App request.

using System.Web.Mvc;

public class AngularAppController : BaseController
    public ActionResult AngularAppView()
        return View();

Then, you have to decide the route where your Angular app will render. On this example it will be /angularapp.

On your ApplicationStarted method, put this code:

  new { controller = "AngularApp", action = "AngularAppView" });

The {*.} syntax is what makes your angular app routes load and not return the 404 page.

If you don’t have an ApplicationStarted method, find out how you to create it here:

Under your Views folder, create a folder with the same name as the controller you set in MapRoute. In this case it will be “AngularApp”.
Inside it, create a view with the same name as the action set you set in MapRoute.

Inside the view put the contents of the index.html of your angular app.
Then you will need to move your angular app files somewhere like you /Assets folder, and edit their paths on the view.

Almost done!

Now you need to edit the routes of your Angular app.
Simply add the route you chose as a prefix to the routes.

From something like this:

const routes: Routes = [
  { path: '', redirectTo: '/dashboard', pathMatch: 'full' },
  { path: '/dashboard', component: DashboardComponent },
  { path: '/detail/:id', component: HeroDetailComponent },
  { path: '/heroes', component: HeroesComponent }

To this:

const routes: Routes = [
  { path: 'angularapp', redirectTo: 'angularapp/dashboard', pathMatch: 'full' },
  { path: 'angularapp/dashboard', component: DashboardComponent },
  { path: 'angularapp/detail/:id', component: HeroDetailComponent },
  { path: 'angularapp/heroes', component: HeroesComponent }

Thanks for reading!

Force Image Cache Refresh Programmatically

The best solution I found, to force the browser cache to refresh for an image, is to modify the image url in the html.

I have an image with this url: “/images/mario-profile-photo.jpeg”.
Change the url to: “/images/mario-profile-photo.jpeg?updated={DateTime.Now.Ticks}“.

So, I lied, sorry! This will make the browser request the image again, because the url is different. It doesn’t really refresh the cache.

Using DateTime.Now.Ticks will force the refresh every time the page loads, so I don’t recommend using it.

If you have the time of when the photo was last updated, use that instead! Something like: {Photo.UpdateDate.Ticks}
This way, you will only request a new image when it is different from the one you already have in cache.

Note: the “?updated=” property is just a name, you can use whatever you want. The important thing is to modify the url.

For Umbraco developers: When saving an image, do not forget to set it’s UpdateDate! Umbraco doesn’t update that property automatically.

Hope this helps,
Thanks for reading!

Syncing Member Types with uSync

This took me longer to figure out than it should have.

uSync has MemberType synchronization disabled by default.

To enable it simply go to Config\uSyncBackOffice.Config and set MemberTypeHandler to true.

<Handlers Group="default" EnableMissing="true">
    <HandlerConfig Name="uSync: DataTypeHandler" Enabled="true" />
    <HandlerConfig Name="uSync: TemplateHandler" Enabled="true" />

    <HandlerConfig Name="uSync: ContentTypeHandler" Enabled="true" />
    <HandlerConfig Name="uSync: MediaTypeHandler" Enabled="true" />
    <HandlerConfig Name="uSync: LanguageHandler" Enabled="true" />
    <HandlerConfig Name="uSync: DictionaryHandler" Enabled="true" />
    <HandlerConfig Name="uSync: MacroHandler" Enabled="true" />
    <HandlerConfig Name="uSync: DataTypeMappingHandler" Enabled="true" />
    <HandlerConfig Name="uSync: MemberTypeHandler" Enabled="true" />
    <!-- content edition - if installed -->
    <HandlerConfig Name="uSync: ContentHandler" Enabled="true" />
    <HandlerConfig Name="uSync: MediaHandler" Enabled="true" />

Thanks for reading!

Mário Nunes

Working with Umbraco 7.6 New Pickers

With the old pickers, we could do something like this:

page.SetValue("myPicker", content.Id);

With the new pickers, we can’t use IDs anymore, we have to use UDIs instead. They look like this:


So how can we get the content UDI?
If we have an IContent, we can simply use the extension

string udi = content.GetUdi().ToString();

If we have an IPublishedContent, we need to do a little bit more work.
Umbraco provides a built in function to create UDIs. To use it, we need these:

using Umbraco.Core;
using static Umbraco.Core.Constants;

Get the UDI like this:

string udi = Udi.Create(UdiEntityType.Document, content.GetKey()).ToString();

If you want to set multiple items, separate the udis with a comma. The resulting string should be like this:

To clean up the code, I created an extension class.

    using Umbraco.Core;
    using Umbraco.Core.Models;
    using Umbraco.Web;
    using static Umbraco.Core.Constants;

    public static class UmbracoExtensions
        /// <summary>
        /// Gets the specified content udi.
        /// </summary>
        /// <param name="content">The content.</param>
        /// <returns>The content udi.</returns>
        public static string GetUdi(this IPublishedContent content)
            return Udi.Create(UdiEntityType.Document, content.GetKey()).ToString();

With this extension, you can set the pickers with IPublishedContent with just one line of code!

page.SetValue("myPicker", content.GetUdi());

So why not use IContent all the time?
To get an IContent, we need to use a service like MediaService or ContentService, they are much slower that getting and IPublishedContent through Umbraco.TypedContent(), which gets it from cache.

UPDATE: Support for member pickers. Other pickers might need additional code too.

public static string GetUdi(this IPublishedContent content)
    string entityType = UdiEntityType.Document;

    if (string.Equals(Models.Member.ModelTypeAlias, content.ContentType.Alias))
        entityType = UdiEntityType.Member;

    return Udi.Create(entityType, content.GetKey()).ToString();

Thanks for reading,
Mário Nunes