A property editor for the Umbraco 17 backoffice. Editors use it to pick one of the languages set up under Settings → Languages. The value is saved as the language's ISO code (for example da-dk), so you can use it in templates to set a culture, filter content, or build language switchers.
- A dropdown with every language configured in Umbraco, shown by name.
- Unique filter (optional): a language already picked on one sibling node isn't offered on the others. Useful for trees such as one node per market or language.
- Allow no value (optional): adds a
NONEoption so the property can be left empty. - Backoffice text in English and Danish.
- Umbraco CMS 17.7.0 or later 17.x
- .NET 10
| Umbraco version | Package version |
|---|---|
| 17 | 17.x |
| 14 | 14.11.0 (no longer maintained; Umbraco 14 is end of life) |
Upgrading from 14.x: 17.0.0 no longer depends on UmbracoKeyValuePropertyEditor, and its API endpoint moved to /umbraco/management/api/v1/umbraco-language-picker/languages. Stored values are unchanged.
dotnet add package UmbracoLanguagePickerBuild and run the site. When you build, the package copies its backoffice files into App_Plugins/LanguagePicker in your project, and dotnet clean removes them again.
-
In the backoffice, go to Settings → Data Types and create a new Data Type.
-
Choose the UmbracoLanguagePicker property editor (flag icon, in the Common group).
-
Set the options you need:
Setting Default What it does Unique Filter off Hides languages already used by this property on sibling nodes. Allow no value off Adds a NONEoption that saves an empty value. -
Add a property using the Data Type to any Document Type.
On existing nodes the picker shows the current language with an Edit button. On new nodes it opens as a dropdown straight away.
The value is a lowercase ISO code string, such as en-us or da-dk. It's an empty string when Allow no value is on and NONE is picked.
@{
var languageCode = Model.Value<string>("language");
}
@if (!string.IsNullOrEmpty(languageCode))
{
var culture = new System.Globalization.CultureInfo(languageCode);
<p>This page is in @culture.DisplayName</p>
}With ModelsBuilder, the generated property is a string.
When Unique Filter is on, the picker asks the server which languages the same property already uses on the node's siblings, meaning the other children of the same parent, or the other root nodes for a node at the root. Those languages are left out of the dropdown. The node's own current value is always available.
Limitations:
- Only published siblings are checked, because the lookup uses the published content cache. Unpublished drafts don't count.
- The filter only changes which options the dropdown shows. Nothing checks the value when a node is saved, so two editors working at the same time can still pick the same language.
- If the siblings can't be read, the picker shows all languages and logs a warning.
The backoffice UI is a Lit web component in UmbracoLanguagePicker/App_Plugins/LanguagePicker, built with Vite.
cd UmbracoLanguagePicker/App_Plugins/LanguagePicker
npm ci
npm run build # type-checks and writes dist/
npm run watch # rebuilds on changeThen build the .NET project from the repository root:
dotnet buildProject layout:
| Path | Purpose |
|---|---|
App_Plugins/LanguagePicker/src/ |
The property editor web component (TypeScript) |
App_Plugins/LanguagePicker/umbraco-package.json |
Registers the property editor, its settings and translations |
App_Plugins/LanguagePicker/Localization/ |
Backoffice translations (en, en-us, da-dk) |
LanguageApiController.cs |
Management API endpoint (GET /umbraco/management/api/v1/umbraco-language-picker/languages) that returns the available language codes |
UmbracoLanguagePickerConverter.cs |
Property value converter, which returns the value as a string |
build/UmbracoLanguagePicker.targets |
Copies the backoffice files into the consuming site on build |
Pushing a tag of the form vX.Y.Z from a commit on main runs the GitHub Actions workflow. It builds the client files, packs the NuGet package with version X.Y.Z, and publishes it to nuget.org.