Localization
Ship your app in more than one language: dates and numbers in the visitor's format, text in their
language, and <html lang> that tells the truth.
Every scaffolded app already ships one language, English, listed in appsettings.json under
Rask:Cultures. Adding a second is an entry in the list that is already there:
{
"Rask": {
"Cultures": [ "en", "hu" ] // the first is the default; add one to ship another
}
}
The object form takes the other settings beside the list:
"Cultures": { "SupportedCultures": [ "en", "hu" ], "DefaultCulture": "hu" }.
The first entry is the default a visitor falls back to. That list is where languages are configured —
there is no CLI flag for it, because the file is where the answer lives and stays
(#854). In the environment it is one variable per entry
(Rask__Cultures__0=en).
A configureCulture callback on AddRask still works and runs after the section. The list is appended to
rather than replaced, so a language added in code joins the configured ones:
builder.Services.AddRask(configureCulture: c => c.SupportedCultures.Add("hu"));
A browser (WebAssembly) app lists them in the same section, read by its build — see WebAssembly apps.
Until you add a second, nothing changes: <html lang="en">, no dir attribute, and no cost on
the render path.
How a visitor's language is chosen
| Order | Source | Notes |
|---|---|---|
| 1 | ?culture=hu |
An explicit act. Also remembered, so a shared link sticks |
| 2 | the culture cookie | A choice they made earlier |
| 3 | Accept-Language / navigator.languages |
What their browser says they read |
| 4 | your first SupportedCultures entry |
The default |
A request for a language you ship in another region still works: hu-HU is served by hu, and hu is
served by a supported hu-HU. A language you do not ship falls through to the default rather than
being honoured.
The language is settled before the first render, on both hosts. That matters more than it sounds:
by the time script could read navigator.language, the page has already painted — and if it painted in
the wrong language the visitor would watch it change.
Why the URL has no language in it
/products/42 is the same page for everyone. That is a deliberate trade:
- a pasted link works for whoever opens it, in their language
- the router, the generated
Url()/Go()helpers and every route value stay culture-neutral - nothing in your app has to thread a culture through link generation
The cost is that you do not get per-language URLs for search engines. If you need those, you need more
than a prefix — canonical tags, hreflang pairs, and a sitemap per language — which is a different
feature with a different design, not a switch to flip.
The cookie
Rask reads and writes ASP.NET's own .AspNetCore.Culture cookie, in ASP.NET's own format. So an
app that also calls UseRequestLocalization() for its non-Rask endpoints, or that shares a host with
MVC, agrees with them rather than holding a second, conflicting preference.
It is deliberately readable from script — the WASM host reads it before the runtime boots, to stamp
lang/dir on the document — so it carries a language tag and never anything else.
A choice made with Set is written by Rask.Web.CookieCulturePersistence, through document.cookie
(Document.SetCookie), so it is remembered over plain HTTP too. Both hosts register it, so there is nothing to
write; register your own IRaskCulturePersistence first to store the choice elsewhere.
Translating your text
Put a catalog per language in Resources/:
// Resources/Strings.en.json — the neutral catalog defines which keys exist
{
"AppTitle": "Welcome",
"Greeting": "Hello, {name}!",
"Home": { "Title": "Dashboard" }
}
// Resources/Strings.hu.json
{
"AppTitle": "Üdvözöljük",
"Greeting": "Szia, {name}!",
"Home": { "Title": "Irányítópult" }
}
They compile into real members:
Div[
H1[Strings.Home.Title],
P[Strings.Greeting(user.Name)]
]
A typo is a compile error. Strings.Greetng(...) is CS0117 and the wrong number of arguments is
CS1501 — at the call site, before anything runs. Nothing renders a bare key to a user.
A string is text wherever a child goes:
P[Strings.Greeting(name)], a bare child,Text.Value(...)andText[Strings.Greeting(name)]all render the same encoded words.
Placeholders
{name} takes object?. {count:int} makes it typed. {price:decimal:C} adds a format specifier,
applied in the visitor's culture.
Names, not positions, because other languages reorder arguments:
{ "M": "{a} then {b}" } // en
{ "M": "{b} majd {a}" } // hu — fine, the same names
What is not fine is a different set of names: that throws FormatException when a Hungarian visitor
first sees the string, so it is RASK051, an error at build time.
Counts
A count is dynamic, so "write two keys and pick one" breaks the moment a language has three categories — and Polish, Russian, Czech and Arabic all do. Write a plural set:
{ "Cart": { "$plural": "count", "one": "{count} item", "other": "{count} items" } }
Span[Strings.Cart(basket.Count)]
Each language supplies the categories it distinguishes:
// Resources/Strings.pl.json — Polish, and correctly no "other"
{ "Cart": { "$plural": "n", "one": "{n} plik", "few": "{n} pliki", "many": "{n} plików" } }
Polish integers never select other; CLDR routes the residual to many. A language whose grammar Rask
does not carry is a build error naming it — better than silently applying English rules and shipping
text that reads as broken to every native speaker.
Missing translations
A key you have not translated yet is a warning (RASK052) and falls back to the neutral text, so the page still works. Gate a release on complete translations by promoting it:
# .editorconfig
dotnet_diagnostic.RASK052.severity = error
Or silence it with = none while translation is in progress.
The same values, four languages
Fixed sample values and an explicit CultureInfo per call — a demo that read the ambient culture would reformat every other demo on this page.
using System.Globalization;
namespace Rask.Site.Features.Localization;
/// <summary>
/// The same three values, formatted for four languages side by side.
/// </summary>
/// <remarks>
/// <para>
/// Two rules make this demo safe to snapshot, and both are load-bearing:
/// </para>
/// <para>
/// <b>Fixed sample values, never <c>DateTime.Now</c>.</b> Every registered demo's markup
/// skeleton is committed as a golden file, and the guide page is screenshotted — a value that
/// moves would make both go stale on a schedule rather than when something actually changed.
/// </para>
/// <para>
/// <b>An explicit <c>CultureInfo</c> per call, never an assignment to
/// <c>CultureInfo.CurrentCulture</c>.</b> A guide page mounts many demos in one render; setting
/// the ambient culture here would reformat every other demo on the page, and the golden would
/// record it.
/// </para>
/// </remarks>
public sealed partial class CultureFormatsDemo : Component
{
private static readonly DateTimeOffset Sample = new(2026, 3, 14, 15, 9, 26, TimeSpan.Zero);
private const decimal Price = 1234.56m;
private const double Ratio = 0.4567;
private static readonly string[] Languages = ["en-US", "hu-HU", "de-DE", "ar-EG"];
protected override Component Render()
{
// A runtime built without culture data formats everything identically, which would make this
// table look broken rather than instructive. Say so instead of showing four identical columns.
if (!Rask.Core.Globalization.RaskCultureResolver.IsGlobalizationSupported)
{
return Ui.Callout.Warning.Icon(Ui.IconName.ExclamationCircle)[
Ui.CalloutText["This build runs with ", Code["InvariantGlobalization"], ", so every culture formats identically. Set ", Code["<RaskGlobalization>true</RaskGlobalization>"], " to ship ICU — see the WASM section of this guide."]
];
}
return Ui.Table[
Ui.TableColumns[
Ui.TableColumn["Language"],
Ui.TableColumn["Date"],
Ui.TableColumn["Money"],
Ui.TableColumn["Percent"]
],
// The enumerable is passed straight in: a `..` spread does not bind against the chain's
// children indexer.
Ui.TableRows[Languages.Select(Row)]
];
}
private static Component Row(string tag)
{
var culture = CultureInfo.GetCultureInfo(tag);
// The tag goes in a data attribute, never a class: the golden records tag names and sorted
// class tokens, so a culture in a class would bake the sample data into the snapshot.
return Ui.TableRow.Data("culture", tag)[
Ui.TableCell[Code[tag]],
Ui.TableCell[Sample.ToString("d", culture)],
Ui.TableCell[Price.ToString("C", culture)],
Ui.TableCell[Ratio.ToString("P1", culture)]
];
}
}Language | Date | Money | Percent |
|---|---|---|---|
en-US | 3/14/2026 | $1,234.56 | 45.7% |
hu-HU | 2026. 03. 14. | 1 235 Ft | 45,7% |
de-DE | 14.03.2026 | 1.234,56 € | 45,7 % |
ar-EG | 14/3/2026 | 1٬234٫56 ج.م. | 45٫7٪ |
Reading the culture in a component
public sealed partial class Receipt : Component
{
protected override Component Render() =>
Div[
P[Total.ToString("C", Culture)],
P[IssuedOn.ToString("d", Culture)]
];
}
Culture is the visitor's, for formatting. UICulture is the language their text is in. IsRightToLeft
answers the layout question.
Reading any of them tells the render cache this component depends on the culture, so a language switch
repaints it. That is why you should read Culture rather than CultureInfo.CurrentCulture — the
ambient value is pinned to the same culture during a render, so it formats correctly, but the cache
cannot see that you read it.
What stays culture-neutral, on purpose
These are wire formats, not display formats, and they do not follow the visitor:
<input type="date">andtype="number"values — the HTML5 wire format is fixed, and the browser localizes the display itself- route values and generated URLs
- reconciliation keys, DOM event payloads, and anything else crossing the socket
If you are formatting a value to send somewhere rather than to show someone, pass
CultureInfo.InvariantCulture explicitly.
Switching language at runtime
public sealed partial class LanguageMenu(IRaskCulture culture) : Component
{
protected override Component Render() =>
Select.OnChange(e => culture.Set(e.Value ?? "en"))[
culture.Supported.Select(c => Option.Value(c.Name)[c.NativeName])
];
}
Set switches the session, remembers the choice, and repaints. No reload.
No template scaffolds this, deliberately (#854).
A new project starts with English in Rask:Cultures; adding a language is another
entry there. That is the whole configuration surface — there is
no --culture flag, because a flag would only restate what the file already says, and it would say it
once at scaffold time while the file goes on being the truth.
Where a language control belongs in your chrome is a different question, and it is a design decision about your app rather than wiring — the same line the styling decisions sit on. So a scaffolded app negotiates language correctly out of the box, and a visitor can be sent to a language by link, but there is no affordance for choosing one until you add the component above.
That is worth stating rather than leaving to be discovered: negotiation working end to end reads very
much like a switcher being present somewhere. RaskCultureNegotiator.TrySelect is kept separate from
Negotiate precisely so an explicit pick is honoured regardless of UseQueryString, which is what
keeps the menu above at ten lines instead of a feature.
When no culture is configured
Culture support is off until SupportedCultures has an entry, and "off" means English: <html lang="en">,
and every date and number formatted in en. Both hosts keep that promise to the first HTML they send:
- Server: the first response and every live render run in the server process's culture — the same one,
so a page never changes language once it is live. Set the process culture (or configure a language) if
that is not the one you want;
UseRequestLocalization()reaches only the first response, never the socket, so it is not a way to pick one. - WebAssembly: the .NET runtime starts in the browser's locale and the prerender in the publishing
machine's, neither of which is the page's. So the host pins
CultureInfo.CurrentCulture,CurrentUICultureand both thread defaults toenbefore the first render, and the prerender does the same before the first page. A Hungarian browser therefore reads "October 2026", as the baked page did, rather than "2026. október" under English labels. Without ICU (RaskGlobalizationoff) the pin is the invariant culture, which is what such an app formats in anyway.
To format in the visitor's language, configure it — Rask:Cultures, or host.UseCulture(c => …) — and the
session's culture takes over: the browser is pinned to the negotiated culture before the first render, and the
prerender bakes every page in the app's default culture, <html lang> included, whatever the publishing
machine's locale.
Right-to-left
A right-to-left culture emits dir="rtl" on <html>; everything else emits no dir at all, because
left-to-right is HTML's default. Use logical CSS properties (margin-inline-start, not margin-left)
and the layout follows.
WebAssembly apps
A browser app has no configuration at run time, so its build reads Rask:Cultures instead, from:
| App | File |
|---|---|
wasm (standalone) |
wwwroot/appsettings.json |
wasm-hosted |
the host's appsettings.json — the ONE list both halves use |
// wwwroot/appsettings.json — published with the app, so anyone can read it: no secrets here
{
"Rask": {
"Cultures": [ "en", "hu" ]
}
}
The list is baked into the bundle and in force before the first render and in the prerender, and
host.UseCulture(c => …) in Program.cs still adds to it, or sets the rest of the options. Because the build
reads it, a change needs a rebuild, and an environment variable on a hosted app's server
(Rask__Cultures__1=hu) reaches the server half only. Another file is named with
<RaskAppSettings>path/to/appsettings.json</RaskAppSettings>.
The cookie and the query key are the ones the options name (CookieName, QueryKey), on both hosts.
WASM and ICU
A WASM app needs culture data (ICU) to format a language, and it is the one part of this feature you can
measure on the download. So the build ships it when Rask:Cultures names a language other than English, and
not otherwise: English is what a runtime without culture data formats in anyway, so the "en" a new app
starts with costs nothing, and adding "hu" turns ICU on with no other edit.
To decide yourself — a language added only in code, with UseCulture — set the property:
<RaskGlobalization>true</RaskGlobalization>
false under a non-English list is obeyed, with a build warning, since every language would then format as
English.
Measured on the WASM showcase, publishing the same trimmed app with and without it:
| raw | brotli (what a host serves) | |
|---|---|---|
| without ICU | 12.44 MB | 3.28 MB |
| with ICU | 16.36 MB | 4.33 MB |
| cost | +3.92 MB | +1.05 MB (+32%) |
Re-measured for #853 and still right: +3.90 MB raw / +1.06 MB brotli (+33%) on the current tree. The figures were always the cost of the shards — see below — which is what has shipped all along.
Roughly a third of that is the icudt*.dat files themselves; the rest is a larger dotnet.native.wasm
and System.Private.CoreLib, because turning globalization on brings back runtime code that invariant
mode trims away. That is why it follows the list rather than being on for every browser app; on server
the runtime already carries ICU and it costs nothing.
Without it every culture formats identically and only the invariant culture resolves — and because Rask's resolver refuses to let a culture pose as supported when the data isn't there, an app that configures languages without ICU starts with an empty supported-language list and says so once at startup rather than once per render.
Translated text works either way — lookup is keyed on a language tag rather than a CultureInfo,
so an app can ship three languages with no ICU at all. Only date/number formatting falls back.
The prerender bakes with the culture data the bundle ships. An English-only app has no ICU, so in the
browser "en" formats with the invariant culture's data — 03/14/2026, 2026 March, ¤1,234.50 — while the
publishing machine has real English (3/14/2026, March 2026, $1,234.50). So the prerender of an app
built with InvariantGlobalization runs without culture data too, and the baked page is the one the browser
then renders: <html lang="en"> and the English strings stay; only the formatting is the invariant
culture's. Turn ICU on (Rask:Cultures with another language, or RaskGlobalization) and both bake and
browser format with real culture data.
One property covers all three halves of this, because each default is a trap on its own:
PredefinedCulturesOnlyotherwise staystrue, andCultureInfo.GetCultureInfo("hu-HU")throws rather than falling back- the runtime otherwise has no culture data at all, so no named culture resolves
What ships, and the one thing to know about it
A globalized WASM publish carries three reduced ICU shards, not one full icudt.dat:
icudt_EFIGS.<hash>.dat English, French, Italian, German, Spanish
icudt_CJK.<hash>.dat Chinese, Japanese, Korean
icudt_no_CJK.<hash>.dat everything else — including Hungarian, and English
The runtime loads one of them, chosen at boot, and it chooses from the visitor's browser
(navigator.languages[0]) rather than from the languages your app ships. So a second language works
for a visitor whose browser is already set to it, and an en+hu app opened in an English browser
loads EFIGS — which has no Hungarian. With PredefinedCulturesOnly=false, hu-HU then resolves, does
not throw, and formats dates in English.
Known limitation, tracked in #853. Rask set
WasmIncludeFullIcuintending to ship full ICU and avoid this; the SDK's property isWasmIncludeFullIcuData, so it was never read. Correcting the spelling turns out not to help either: that property is honoured only by theWasmAppBuilderbundle path, and a Rask app publishes throughMicrosoft.NET.Sdk.WebAssembly, whose pipeline has no ICU handling of its own. Measured — publishing with the propertytrueandfalseproduces byte-identical output.If your app ships more than one language and its speakers may arrive with a different browser language, be aware of this. A single-language app is unaffected.
Translating the framework's own text
Rask draws a little text of its own — the pager's "Showing 1 to 10 of 13 results", a select's "No results
found", a date picker's "Select a date", the names a screen reader hears for a close button. Every one of
them is a RaskString key with its English beside it in the code, and is looked up in this order:
- your app's
Resources/RaskStrings.{culture}.json, if it has the key - the UI kit's own translation —
Rask.Uiships Hungarian (hu) beside its English - the English
So an app that lists hu in SupportedCultures gets a Hungarian pager, select, date picker, editor toolbar
and data grid with no catalog of its own, and a language switch repaints them like any other text. The kit's
translations apply only to the languages your app says it ships — an app with no SupportedCultures keeps
the English whatever the server's or the browser's language is. Month and weekday names, dates and numbers
are not in any catalog: they come from the culture.
Adding a language, or changing a word
The reserved catalog is an ordinary JSON file whose keys are RaskString members. Write the keys you want
and leave the rest: anything you have not translated falls through to the kit's own translation, then to
the English.
// Resources/RaskStrings.hu.json — the kit already speaks Hungarian. This overrides two of its words.
{
"ConfirmLeaveStay": "Nem",
"ConfirmLeaveLeave": "Igen"
}
// Resources/RaskStrings.de.json — a language the kit does not ship: the pager and the form controls.
{
"PaginationSummary": "{0}–{1} von {2} Ergebnissen",
"PaginationPrevious": "« Zurück",
"PaginationNext": "Weiter »",
"SelectEmpty": "Keine Ergebnisse",
"SelectLoading": "Wird geladen…",
"SelectSearchPlaceholder": "Suchen…",
"SelectSearchClear": "Suche leeren",
"SelectClear": "Auswahl aufheben",
"SelectSelectedSuffix": "ausgewählt",
"DatePickerPlaceholder": "Datum wählen",
"DatePickerRangePlaceholder": "Zeitraum wählen",
"DatePickerConfirm": "Übernehmen",
"DatePickerCancel": "Abbrechen",
"CalendarToday": "Heute",
"PickerPreviousMonth": "Vorheriger Monat",
"PickerNextMonth": "Nächster Monat",
"TimePickerPlaceholder": "Uhrzeit wählen",
"PickerClear": "Löschen",
"InputClear": "Eingabe löschen",
"InputCopy": "In die Zwischenablage kopieren",
"InputTogglePassword": "Passwort ein- oder ausblenden",
"InputChooseFile": "Datei auswählen",
"InputChooseFiles": "Dateien auswählen",
"InputNoFile": "Keine Datei ausgewählt",
"ModalClose": "Dialog schließen"
}
No neutral file: the framework's English lives in its own code. A misspelled key is a build error (RASK051) listing the valid names.
A text that carries values numbers them — {0}, {1}, {2} — so a translation puts them in its own
order, and may give one a .NET format: the Hungarian pager is "{2} találatból {0}–{1}.", and
"{2:N0}" would group the total's thousands. The values are written in the visitor's culture. Asking for a
value the text does not carry ({3} in the pager's summary), or naming one ({total}), is a build error
too. There are no plural forms here: none of these texts changes with its number in English, and a count
stands before a singular in Hungarian.
The kit's own Hungarian is the same kind of file, src/Rask.Ui/Resources/RaskStrings.hu.json, compiled by
the same generator. A component library of your own ships translations for the framework texts it draws the
same way — the file, and <RaskStringsLibrary>true</RaskStringsLibrary> in its project, which registers
them a layer under the app's catalog instead of in its place.
Every key
What each key says in English, and where it is drawn. A component's own props still win where it has them —
Ui.Select.Empty("…"), Ui.DatePicker.Placeholder("…"), Ui.ConfirmLeave.Stay("…"): the catalog is what
they say when you set nothing.
| Key | Where | English |
|---|---|---|
PickerPreviousMonth |
Calendar | Previous month |
PickerNextMonth |
Calendar | Next month |
PickerHour |
Time picker | Hour |
PickerMinute |
Time picker | Minute |
PickerSecond |
— (nothing reads it today) | Second |
PickerClear |
Time picker | Clear |
NotFoundTitle |
Not-found page | Page not found |
NotFoundBody |
Not-found page | No route is registered for {0}. |
NotFoundBackHome |
Not-found page | Back to home |
ErrorHeading |
Error page | Something went wrong |
ErrorTryAgain |
Error page | Try again |
ErrorReload |
Error page | Reload this page |
PaginationSummary |
Pagination | Showing {0} to {1} of {2} results |
PaginationPrevious |
Pagination | « Previous |
PaginationNext |
Pagination | Next » |
TableEmpty |
Table drawn from a query | No results. |
CalendarToday |
Calendar | Today |
DatePickerPlaceholder |
Date picker | Select a date |
DatePickerRangePlaceholder |
Date picker | Select a date range |
DatePickerConfirm |
Date picker | Select date |
DatePickerCancel |
Date picker | Cancel |
DatePickerMonth |
Date picker | Month |
DatePickerDay |
Date picker | Day |
DatePickerYear |
Date picker | Year |
DatePickerMonthPlaceholder |
Date picker | mm |
DatePickerDayPlaceholder |
Date picker | dd |
DatePickerYearPlaceholder |
Date picker | yyyy |
DateRangePresetToday |
Date picker | Today |
DateRangePresetYesterday |
Date picker | Yesterday |
DateRangePresetThisWeek |
Date picker | This Week |
DateRangePresetLastWeek |
Date picker | Last Week |
DateRangePresetLast7Days |
Date picker | Last 7 Days |
DateRangePresetThisMonth |
Date picker | This Month |
DateRangePresetLastMonth |
Date picker | Last Month |
DateRangePresetThisQuarter |
Date picker | This Quarter |
DateRangePresetLastQuarter |
Date picker | Last Quarter |
DateRangePresetThisYear |
Date picker | This Year |
DateRangePresetLastYear |
Date picker | Last Year |
DateRangePresetLast14Days |
Date picker | Last 14 Days |
DateRangePresetLast30Days |
Date picker | Last 30 Days |
DateRangePresetLast3Months |
Date picker | Last 3 Months |
DateRangePresetLast6Months |
Date picker | Last 6 Months |
DateRangePresetYearToDate |
Date picker | Year to Date |
DateRangePresetTomorrow |
Date picker | Tomorrow |
DateRangePresetNextWeek |
Date picker | Next Week |
DateRangePresetNext7Days |
Date picker | Next 7 Days |
DateRangePresetNextMonth |
Date picker | Next Month |
DateRangePresetNextQuarter |
Date picker | Next Quarter |
DateRangePresetNextYear |
Date picker | Next Year |
DateRangePresetNext14Days |
Date picker | Next 14 Days |
DateRangePresetNext30Days |
Date picker | Next 30 Days |
DateRangePresetNext3Months |
Date picker | Next 3 Months |
DateRangePresetNext6Months |
Date picker | Next 6 Months |
DateRangePresetAllTime |
Date picker | All Time |
DateRangePresetCustom |
Date picker | Custom |
SelectLoading |
Select | Loading... |
SelectEmpty |
Select | No results found |
SelectSearchPlaceholder |
Select | Search... |
SelectSearchClear |
Select | Clear command input |
SelectClear |
Select | Clear selected |
SelectSelectedSuffix |
Select | selected |
TimePickerPlaceholder |
Time picker | Select a time |
TimePickerMeridiem |
Time picker | AM/PM |
TimePickerHourPlaceholder |
Time picker | hh |
TimePickerMinutePlaceholder |
Time picker | mm |
EditorLabel |
Editor | Rich text editor |
EditorToolbar |
Editor | Formatting |
EditorBold |
Editor | Bold |
EditorItalic |
Editor | Italic |
EditorStrike |
Editor | Strikethrough |
EditorUnderline |
Editor | Underline |
EditorBullet |
Editor | Bullet list |
EditorOrdered |
Editor | Ordered list |
EditorBlockquote |
Editor | Blockquote |
EditorCode |
Editor | Code |
EditorHighlight |
Editor | Highlight |
EditorSubscript |
Editor | Subscript |
EditorSuperscript |
Editor | Superscript |
EditorUndo |
Editor | Undo |
EditorRedo |
Editor | Redo |
EditorLink |
Editor | Insert link |
EditorUnlink |
Editor | Unlink |
EditorAlign |
Editor | Align |
EditorAlignLeft |
Editor | Left |
EditorAlignCenter |
Editor | Center |
EditorAlignRight |
Editor | Right |
EditorHeading |
Editor | Styles |
EditorHeadingText |
Editor | Text |
EditorHeading1 |
Editor | Heading 1 |
EditorHeading2 |
Editor | Heading 2 |
EditorHeading3 |
Editor | Heading 3 |
InputClear |
Input | Clear input |
InputCopy |
Input | Copy to clipboard |
InputTogglePassword |
Input | Toggle password visibility |
InputChooseFile |
Input | Choose file |
InputChooseFiles |
Input | Choose files |
InputNoFile |
Input | No file chosen |
ModalClose |
Modal | Close modal |
ConfirmLeaveStay |
Confirm leave | Stay |
ConfirmLeaveLeave |
Confirm leave | Leave |
OtpCharacter |
OTP input | Character {0} of {1} |
SliderRangeStart |
Slider | {0} start range |
SliderRangeEnd |
Slider | {0} end range |
SidebarToggle |
Sidebar | Toggle sidebar |
SidebarSearch |
Sidebar | Search |
CommandEmpty |
Command | No results found |
FileItemRemove |
File upload | Remove file |
ValidationRequired |
Validation | This field is required. |
ValidationWholeNumber |
Validation | Enter a whole number. |
ValidationNumber |
Validation | Enter a number. |
ValidationNumberRange |
Validation | The number is out of range. |
ValidationDate |
Validation | Enter a valid date. |
ValidationTime |
Validation | Enter a valid time. |
FormSaveFailed |
Form | The save failed. Please try again. |
ErrorReference |
Error page | The problem has been recorded. If it keeps happening, quote this reference: {0} |
HandlerFailed |
Toast | That did not work. Please try again. |
ErrorTitle |
Error page | Application error |
CarouselRole |
Carousel | carousel |
CarouselLabel |
Carousel | Items |
CarouselSlideRole |
Carousel | slide |
CarouselSlideLabel |
Carousel | {0} of {1} |
CarouselPrevious |
Carousel | Previous slide |
CarouselNext |
Carousel | Next slide |
CarouselIndicators |
Carousel | Choose slide to display |
CarouselShowSlide |
Carousel | Show slide {0} |
PhoneChangeCountry |
Phone | Change country |
ConnectionReconnecting |
Reconnect overlay | Reconnecting… |
ConnectionOffline |
Reconnect overlay | You're offline — waiting to reconnect… |
ConnectionStillTrying |
Reconnect overlay | Still trying to reconnect… |
ConnectionRetry |
Reconnect overlay | Retry now |
ConnectionReload |
Reconnect overlay | Reload |
ConnectionUpdating |
Reconnect overlay | Updating… |
ConnectionAuthenticating |
Reconnect overlay | Authenticating… |
ConnectionSessionTimedOut |
Reconnect overlay | Your session timed out. Reload to continue. |
CommandClear |
Command | Clear command input |
CommandClose |
Command | Close command modal |
HandlerForbidden |
Toast | You do not have permission to do that. |
PageForbidden |
Page | You do not have permission to view this page. |
ConfirmHeading |
Confirm | Confirm |
ConfirmYes |
Confirm | Yes |
ConfirmNo |
Confirm | No |
PdfPageNumber |
PDF foot (Rask.Pdf) | {0} / {1} |
Filters |
Filters | Filters |
FiltersClear |
Filters | Clear filters |
FiltersClearAll |
Filters | Clear all |
FiltersClose |
Filters | Close |
FilterRemove |
Filters | Remove filter {0} |
ColorPickerOpen |
Color picker | Open color picker |
ColorPickerOpenWith |
Color picker | Open color picker, {0} |
ColorPickerInput |
Color picker | Color |
ColorPickerPlaceholder |
Color picker | Enter a color |
ColorPickerArea |
Color picker | Saturation and brightness |
ColorPickerAreaRole |
Color picker | 2D color picker |
ColorPickerAreaValue |
Color picker | Saturation {0}%, brightness {1}% |
ColorPickerHue |
Color picker | Hue |
ColorPickerOpacity |
Color picker | Opacity |
ColorPickerValue |
Color picker | Color value |
ColorPickerSwatches |
Color picker | Color swatches |
ColorPickerSelected |
Color picker | {0} selected |
ColorPickerDropper |
Color picker | Pick a color from the screen |
ColorPickerClear |
Color picker | Clear color |
ColorPickerCancel |
Color picker | Cancel |
ColorPickerSelect |
Color picker | Select |
ValidationColor |
Validation | Enter a valid color. |
ColorSwatchRed |
Color picker | Red |
ColorSwatchOrange |
Color picker | Orange |
ColorSwatchAmber |
Color picker | Amber |
ColorSwatchYellow |
Color picker | Yellow |
ColorSwatchGreen |
Color picker | Green |
ColorSwatchTeal |
Color picker | Teal |
ColorSwatchSky |
Color picker | Sky |
ColorSwatchIndigo |
Color picker | Indigo |
ColorSwatchPurple |
Color picker | Purple |
ColorSwatchPink |
Color picker | Pink |
ColorSwatchRose |
Color picker | Rose |
ColorSwatchOrangeLight |
Color picker | Orange light |
ColorSwatchAmberLight |
Color picker | Amber light |
ColorSwatchLime |
Color picker | Lime |
ColorSwatchEmerald |
Color picker | Emerald |
ColorSwatchCyan |
Color picker | Cyan |
ColorSwatchIndigoLight |
Color picker | Indigo light |
ColorSwatchVioletLight |
Color picker | Violet light |
ColorSwatchPinkLight |
Color picker | Pink light |
ColorSwatchRoseLight |
Color picker | Rose light |
ColorSwatchStone |
Color picker | Stone |
ColorSwatchSlate |
Color picker | Slate |
ColorSwatchBlack |
Color picker | Black |
ColorSwatchWhite |
Color picker | White |
DatePickerConfirmRange |
Date picker | Select range |
DatePickerPresetsPlaceholder |
Date picker | Choose predefined range... |
Docker
The scaffolded image is Debian-based (mcr.microsoft.com/dotnet/aspnet) and ships ICU, so nothing to
do. If you switch to an Alpine base, set InvariantGlobalization=false and install icu-libs — a
container without them formats every culture identically.
See also
- Diagnostics — RASK051 and RASK052 in full
- Accessibility —
langon a run of text, versus on the document