If you want to create your own content finder implement the IContentFinder interface:

    public interface IContentFinder
      bool TryFindContent(PublishedContentRequest contentRequest);
    // Some are registered by default
    // But feel free to use your owns
    public class ContentFinderResolver
    { … }

    Umbraco runs all content finders, stops at the first one that returns true. Finder can set content, template, redirect…


    public class MyContentFinder : IContentFinder
      public bool TryFindContent(PublishedContentRequest request)
        var path = request.Uri.GetAbsolutePathDecoded();
        if (!path.StartsWith("/woot"))
        return false; // not found
        // have we got a node with ID 1234?
        var contentCache = UmbracoContext.Current.ContentCache;
        var content = contentCache.GetById(1234);
        if (content == null) return false; // not found
        // render that node
        request.PublishedContent = content;
        return true;

    Example Default content finder

    public class ContentFinderByNiceUrl : IContentFinder
      public virtual bool TryFindContent(PublishedContentRequest request)
        string path = request.HasDomain
          // eg. 5678/path/to/node
          ? request.Domain.RootNodeId.ToString() + …
          // eg. /path/to/node
          : request.Uri.GetAbsolutePathDecoded();
        var node = FindContent(request, path);
        return node != null;

    Default finder will look for content under the domain root. This is an un-breaking change.

    Example wire up

    this example shows how to add custom content finder to (and how to remove ContentFinderByNiceUrl from) the ContentFinderResolver.

    public class MyApplication : ApplicationEventHandler
      protected override void ApplicationStarting(…) 
        // Insert my finder before ContentFinderByNiceUrl
          .InsertTypeBefore<ContentFinderByNiceUrl, MyContentFinder>();
        // Remove ContentFinderByNiceUrl


    To set your own 404 finder create an IContentFinder and set it as the ContentLastChanceFinder. A ContentLastChanceFinder will always return a 404 status code. This example creates a new implementation of the IContentFinder and checks whether the requested content could not be found by using the default Is404 property presented in the PublishedContentRequest class.

    public class My404ContentFinder : IContentFinder {
    	public bool TryFindContent(PublishedContentRequest contentRequest) {
            //logic to find your 404 page and set it to contentRequest.PublishedContent
         CultureInfo culture = null;
            if (contentRequest.HasDomain) {
                culture = CultureInfo.GetCultureInfo(contentRequest.UmbracoDomain.LanguageIsoCode);
            //replace 'home_doctype_alias' with the alias of your homepage
            IPublishedContent rootNode = UmbracoContext.Current.ContentCache.GetByXPath("root/home_doctype_alias").FirstOrDefault(n => n.GetCulture().ThreeLetterWindowsLanguageName == culture.ThreeLetterWindowsLanguageName);
            //replace '404_doctype_alias' with the alias of your 404 page
            IPublishedContent notFoundNode = UmbracoContext.Current.ContentCache.GetByXPath(String.Format("root/homeDocType[id={0}]/404_doctype_alias", rootNode.Id)).FirstOrDefault(n => n.GetCulture().ThreeLetterWindowsLanguageName == culture.ThreeLetterWindowsLanguageName);
            if (notFoundNode != null) {
                contentRequest.PublishedContent = notFoundNode;
            } else if (rootNode != null) {
                contentRequest.PublishedContent = rootNode;
            } else {
                contentRequest.PublishedContent = UmbracoContext.Current.ContentCache.GetAtRoot().FirstOrDefault(n => n.GetTemplateAlias() != "");
            return contentRequest.PublishedContent != null;

    Example on how to register your own implementation:

    ContentLastChanceFinderResolver.Current.SetFinder(new My404ContentFinder());