Multilingual support for MVC sites
Currently, Kentico MVC sites unfortunately do not have a working culture context. The only thing we provide is a solution in our Dancing Goat sample site that sets the thread culture based on the route data via MultiCultureMvcRouteHandler. For general MVC projects that do not handle this, the thread culture just falls back to the user's environment/system culture. So what are the best practices for handling multilingual support in MVC sites?
First, you need to set up functionality that detects and sets the current culture for each request. You can then localize the content displayed on the site's pages. One of the possible options for determining the culture of page requests is to use culture prefixes in your site's routes. For example:
- English: www.domain.com/en-us/home
- German: www.domain.com/de-de/home
It is necessary to parse the culture from the route prefix and then set the current culture for the MVC application, as you can see in the following example:
RouteConfig:
using System.Web.Mvc;
using System.Web.Routing;
...
public static void RegisterRoutes(RouteCollection routes)
{
...
// Parses a URL containing a culture route prefix
var route = routes.MapRoute(
name: "Default",
url: "{culture}/{controller}/{action}",
defaults: new { controller = "Home", action = "Index" },
constraints: new { culture = new SiteCultureConstraint() }
);
// Assigns a custom route handler to the route
route.RouteHandler = new MultiCultureMvcRouteHandler();
MultiCultureMvcRouteHandler:
using System.Globalization;
using System.Threading;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
public class MultiCultureMvcRouteHandler : MvcRouteHandler
{
protected override IHttpHandler GetHttpHandler(RequestContext requestContext)
{
// Retrieves the requested culture from the route
var cultureName = requestContext.RouteData.Values["culture"].ToString();
try
{
// Creates a CultureInfo object from the culture code
var culture = new CultureInfo(cultureName);
// Sets the current culture for the MVC application
Thread.CurrentThread.CurrentUICulture = culture;
Thread.CurrentThread.CurrentCulture = culture;
}
catch
{
// Handles cases where the culture parameter of the route is invalid
// Returns a 404 status in this case, but you can also log an error, set a default culture, etc.
requestContext.HttpContext.Response.StatusCode = 404;
}
return base.GetHttpHandler(requestContext);
}
}
SiteCultureConstraint:
using System.Web;
using System.Web.Routing;
using CMS.SiteProvider;
// Constraint that restricts culture parameter values
// Only allows the codes of cultures assigned to the current site in Kentico
public class SiteCultureConstraint : IRouteConstraint
{
public bool Match(HttpContextBase httpContext,
Route route,
string parameterName,
RouteValueDictionary values,
RouteDirection routeDirection)
{
string cultureCodeName = values[parameterName]?.ToString();
return CultureSiteInfoProvider.IsCultureOnSite(cultureCodeName, SiteContext.CurrentSiteName);
}
}
Now you can load the correct culture version of retrieved pages based on the current culture of the request.
We also updated our documentation (for Kentico 9, 10 and 11) so you can find instructions on how to localize MVC site content here.