TwoSky.WebComponents.LanguageBanner 1.1.0

dotnet add package TwoSky.WebComponents.LanguageBanner --version 1.1.0
                    
NuGet\Install-Package TwoSky.WebComponents.LanguageBanner -Version 1.1.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="TwoSky.WebComponents.LanguageBanner" Version="1.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="TwoSky.WebComponents.LanguageBanner" Version="1.1.0" />
                    
Directory.Packages.props
<PackageReference Include="TwoSky.WebComponents.LanguageBanner" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add TwoSky.WebComponents.LanguageBanner --version 1.1.0
                    
#r "nuget: TwoSky.WebComponents.LanguageBanner, 1.1.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package TwoSky.WebComponents.LanguageBanner@1.1.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=TwoSky.WebComponents.LanguageBanner&version=1.1.0
                    
Install as a Cake Addin
#tool nuget:?package=TwoSky.WebComponents.LanguageBanner&version=1.1.0
                    
Install as a Cake Tool

LanguageBanner

A language selection banner web component that detects when the user's preferred language differs from the current page language. It offers to persist the current language as the user's preference or dismiss the banner for the session.

This plugin is only compatible with the Web3 Vidyano client.

Installation

After installing the NuGet package, add the following import to your app.ts:

import "../language-banner/language-banner";

Rebuild the frontend code after making this change. Then choose how the component reaches the page:

Stock Vidyano client (<vi-app>) — automatic injection

Opt a website in by adding a LanguageBanner key to its entry in App_Data/websites.json:

"CareAdmin": { "Type": 4, "Bindings": ["*/careadmin"], "LanguageBanner": "menu-footer" }

The plugin then injects the following element as the first child of <vi-app> when that website's index.html is served:

<ts-language-banner slot="menu-footer" display-mode="dropdown" theme="menu"></ts-language-banner>

vi-app forwards the menu-footer slot into the menu footer; with theme="menu" the component overlays the <vi-user> actions row, centred between the settings and sign-out buttons. Selecting a language switches the session language and reloads, after which the mismatch banner offers to use that language everywhere — the same flow as manual placement. Nothing is injected when the key is missing, when the page has no <vi-app>, or when a ts-language-banner element is already present.

Custom pages — manual placement

For a custom shell (e.g. a <ca-app> webshop) add the element yourself, in the navigation bar:

<ts-language-banner display-mode="dropdown"></ts-language-banner>

Both can be combined in one application: enable the key on the stock website only and keep manual placement in the custom page.

UserSettings "Language" field

Installing the plugin registers a CronosAdvanced.RegisterLoadUserSettingsHook handler that removes the Language attribute from Vidyano's UserSettings persistent object — but only for requests coming through a website that has the LanguageBanner key, i.e. where the dropdown replaces it. Websites without the key keep the field. To keep the field everywhere, set this in Startup:

Service.Plugins.LanguageBanner.HideUserSettingsLanguage = false;

Note: a module Advanced that overrides LoadUserSettings must call base.LoadUserSettings(args) or the handler does not run.

Display Modes

The component supports two display modes via the display-mode attribute:

Shows a globe icon with the current language code. Clicking opens a dropdown menu with available languages.

<ts-language-banner display-mode="dropdown"></ts-language-banner>

Buttons

Shows all available languages as side-by-side buttons, with the active language highlighted.

<ts-language-banner display-mode="buttons"></ts-language-banner>

Attributes

Attribute Default Description
display-mode dropdown dropdown or buttons (see above)
theme (empty) menu adapts the component to the stock vi-app shell: the dropdown sits in the vi-user actions row, in a gap the component reserves between the middle buttons (inline margins on vi-user's buttons, sized to the trigger, so it also works when privacy/profiler/feedback buttons are enabled), the popup opens upwards; the mismatch banner overlays the top of the page as in every other placement (it is rendered as a top-layer popover, so it always stays above the application)
hide-banner off Never render the language mismatch banner
persist-on-select off Selecting a language first calls UpdateApplicationLanguage (persists Person.ApplicationLanguage, refreshes the PreferredLanguage cookie) and then reloads. Without it a selection only switches the session language via the requestedLanguage cookie

hide-banner and persist-on-select are meant to be used together for a silent switch: the selection is saved immediately, so preferred and current language cannot diverge and the banner is not needed. Neither is set by default nor by the automatic injection, so the default flow is always: session switch + banner offering to persist.

Language Mismatch Banner

When the user's preferred language (stored in a PreferredLanguage cookie, set by CronosCore) differs from the current page language, a banner appears with two options:

  • "Use {language} everywhere" - Calls the CronosWeb.UpdateApplicationLanguage endpoint to persist the current language as the user's Person.ApplicationLanguage
  • "Dismiss for now" - Hides the banner until the next page load

Events

The component fires the following custom events:

Event Detail Description
language-persist { language: string } User clicked "Use everywhere"
language-dismiss { from: string, to: string } User clicked "Dismiss"
language-select { language: string } User selected a language from dropdown/buttons

Translatable Messages

The plugin registers the following client-side messages (en, nl, fr):

  • LanguageBanner_Message - The mismatch banner message
  • LanguageBanner_UseEverywhere - The persist button label
  • LanguageBanner_Dismiss - The dismiss button label
  • LanguageBanner_LanguageName_en - Language name for English
  • LanguageBanner_LanguageName_nl - Language name for Dutch
  • LanguageBanner_LanguageName_fr - Language name for French

Styling

The component uses Shadow DOM. You can customize its appearance via CSS custom properties and ::part() selectors.

CSS Custom Properties

Override these on the host element or any ancestor:

Variable Default Description
--language-banner-bg #f8f9fa Banner background color
--language-banner-color #212529 Banner text color
--language-banner-padding 12px 20px Banner padding
--language-banner-shadow 0 2px 5px rgba(0,0,0,0.1) Banner box shadow
--language-banner-z-index 1050 Banner z-index
--language-banner-font-size 14px Banner font size
--language-banner-btn-padding 8px 15px Button padding
--language-banner-btn-radius 4px Button border radius
--language-banner-primary-bg #007bff "Use everywhere" button background
--language-banner-primary-color white "Use everywhere" button text color
--language-banner-primary-hover-bg #0056b3 "Use everywhere" button hover background
--language-banner-secondary-bg #6c757d "Dismiss" button background
--language-banner-secondary-color white "Dismiss" button text color
--language-banner-secondary-hover-bg #545b62 "Dismiss" button hover background

Example:

ts-language-banner {
  --language-banner-primary-bg: var(--theme-color);
  --language-banner-primary-hover-bg: var(--theme-color-lighter);
  --language-banner-bg: var(--theme-color-faint);
}

CSS ::part() Selectors

For full styling control, target individual elements:

Part name Element
banner The mismatch notification banner
banner-content Banner message container
banner-icon Globe icon in the banner
banner-message Banner text
banner-actions Banner button container
btn-primary "Use everywhere" button
btn-secondary "Dismiss" button
dropdown Dropdown mode container
trigger Dropdown trigger button
menu Dropdown menu
menu-item Dropdown menu item
buttons Buttons mode container
button Individual language button
button-active Active language button

Example:

ts-language-banner::part(banner) {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
}

ts-language-banner::part(btn-primary) {
  background-color: white;
  color: #764ba2;
}

Dependencies

  • CronosCore (CronosCore#742) - Provides:
    1. PreferredLanguage cookie set on login from Person.ApplicationLanguage (opt-in via PreferredLanguageCookie.Enabled)
    2. CronosWeb.UpdateApplicationLanguage() — endpoint that forwards to CronosCentral via ClientInvoker and refreshes the cookie on success
    3. CronosAdvanced.RegisterLoadUserSettingsHook() (CronosCore.Common 3.31.0+) — used to hide the UserSettings Language field. The generated Service/Plugins/LanguageBanner.g.cs compiles inside your project against the CronosCore version you reference; the package itself declares no CronosCore dependency.

Consuming App Setup

Enable the preferred language cookie in your authenticator service constructor:

public MyAuthenticatorService()
    : base(..., preferredLanguageCookie: PreferredLanguageCookie.Enabled)
{ }

No additional wiring is needed — CronosWeb.UpdateApplicationLanguage() handles the CronosCentral API call and cookie refresh automatically. Requires services.AddCronosCore() to be registered.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net8.0

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.1.0 79 8/27/2026
1.0.1 2,075 3/9/2026
1.0.0 291 3/3/2026