How to localise your 404 custom error page in Episerver

I feel like there is a better / easier way of doing this but I couldn’t find a resource online that works (and there isn’t much I could find at the time of writing). So I’m sharing this post as an option that works, incase you haven’t found a better solution. For those who have better solutions, please share! 🙂

Note: This post assumes you already have a 404 error page set up and that you’re using Geta’s 404 Handler

The problem with a web.config that has a 404 path without any language context

I’ve tried adding the prefixLanguageFilePath to the <error ..> tag in the httpErrors but that did not work. This is what it looks like:

<httpErrors errorMode="Custom" existingResponse="Replace">
   <remove statusCode="404" />
   <error statusCode="404" path="/404" responseMode="ExecuteURL" />
</httpErrors>

As you can see, all 404 requests are served with a response from the URL “/404/, which means even if I attempted to navigate to say a “Polish” page with the URL “abc.com/pl/some-error-page”, it will always serve the response from the URL “abc.com/404/”, instead of “abc.com/pl/404/”.

Add logic to determine the language before serving the site-configured Error page path

Instead of blindly returning the requested 404 page, I had to check the original 404 URL and determine if there is a language path in the URL. So I added this private method in my ErrorPageController.Index() action:

public class ErrorPageController : PageControllerBase<ErrorPage>
{
   [BVNetwork.NotFound.Core.NotFoundPage.NotFoundPage]
   public ActionResult Index(ErrorPage currentPage)
   {
      currentPage = GetLocalisedOrDefaultErrorPage(currentPage);

      var model = new PageViewModel<ErrorPage>(currentPage);

      if (!PageEditing.PageIsInEditMode)
      {
         Response.Clear();
         Response.StatusCode = currentPage.ErrorCode;
         Response.TrySkipIisCustomErrors = true;
      }

      return View(model);
   }
}

Here’s my implementation of the GetLocalisedOrDefaultErrorPage() method:

private ErrorPage GetLocalisedOrDefaultErrorPage(ErrorPage errorPage)
{
   // Determine language of the NotFoundUrl
   if (!string.IsNullOrEmpty(ViewBag.NotFoundUrl))
   {
      var uri = new Uri(ViewBag.NotFoundUrl);

      // if URI segments of the NotFoundUrl are composed of: 1) "/", 2) "{lang}/" (i.e. "/pl/incorrecturl")
      // then load the correct language of the Error page
      if (uri.Segments.Length > 2 && uri.Segments[0] == "/" && uri.Segments[1].EndsWith("/"))
      {
         var firstWordSegmentInUrl = uri.Segments[1].Substring(0, uri.Segments[1].Length - 1);
         // iterate over the existing languages for the error page
	 // and check if any of the languages' URL segment matches the first segment of the accessed URL
	 foreach (var language in errorPage.ExistingLanguages)
	 {
	    string languageSegment = "";
	    if (!_languageSegmentMatcher.TryGetLanguageUrlSegment(language.Name, out languageSegment))
	    {
	       languageSegment = language.Name;
	    }

	    if (languageSegment == firstWordSegmentInUrl)
	    {
	       var errorPageInLanguage = _contentLoader.Get(errorPage.ContentLink, language);
	       if (errorPageInLanguage != null)
	       {
		  errorPage = errorPageInLanguage;
		  _updateCurrentLanguage.UpdateLanguage(language.Name);
	       }								
	    }
	 }
      }
   }

   return errorPage;
}

It’s time to test your 404 pages

If you try to navigate to the URL’s with a language path, it should now try to locate whether you have an Error page for that specific language. Otherwise, it’ll try to serve the default custom Error path.

  • abc.com/pl/some-error should return a Polish page
  • abc.com/some/error should return the default error page (i.e. English)

I’m interested to see other (better) solutions, so please share if you know of one!

%d bloggers like this: