The basic globalization in ASP.NET pretty simple: you create resource (.resx) file for every supported language and include it in App_GlobalResources. ASP.NET will compile it and load on demand. If you put your resources in labels.resx, in your code you can access individual resource like this:

using System.Globalization;
Resources.labels.yourResourceName

That takes care of back-end part, and when using built-in ASP.NET controls this is all you really need. Any labels in application can be defined with runat=server and will be translated on the server and then included in the HTML. Nice. But with JavaScript taking bigger part in web development, how do you extend this to the front-end world?

In BlogEngine, we have helper class (Core/Web/BlogCulture.cs) that responsible for including all globalization resources for every base page. It is included fore example as "en-us.res.axd" as very first script in the page header, so it is available for all other scripts. For other languages instead of "en-us" will be generated script corresponding to localized resource. Anywhere in JavaScript you can get localized string as:

BlogEngineRes.i18n.yourResourceName

And for admin scripts, as:

BlogAdmin.i18n.yourResourceName

To make it less verbose, AngularJS code in admin defines a shortcut on root level, so any Angular script or HTML view can just use lbl.resourceName:

$rootScope.lbl = BlogAdmin.i18n;{{lbl.email}}

Scripts are different for site and admin because admin has lots more resources and site should be as light and fast as possible. Also, we don't need every single resource in JavaScript, some only needed on the back-end. To figure out what resources needed on the front-end, BlogEngine uses "App_Data/labels.txt" file. Only resources listed in this file will be available for JavaScript. As a fall-back, core resources also hard-coded and preloaded if this file is missing.

For any person who maintains specific language used by BlogEngine.NET it means things generally not changes. You open .resx file for a language and sync it with "labels.resx" that is a base resource file. But if you found not-translated label in application and want to help localizing it, make sure resource exists in "App_Data/labels.txt" if it is used by JavaScript. Add it there if not, otherwise you'll get an error on page load.

Couple tools that can make managing localization a bit easier: