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!

Discover more from Nicola Ayan

Subscribe now to keep reading and get access to the full archive.

Continue reading