User Preferences recipe
Source: 10_UserPreferences/ · how to add a custom page under the user-preferences sidebar mode and persist its settings.
Two halves
In src/App.cs, the recipe subscribes to App.Sidebar.OnSidebarRebuild_BeforeFooter and adds a button when mode == App.Sidebar.Mode.UserPreferences:
case App.Sidebar.Mode.UserPreferences:
{
var btn = new SidebarButton("recipe-prefs", UIcons.SlidersHSquare, "Recipe Preferences")
.OnClick(() => Router.Navigate(UserPreferencesRecipeView.PreferencesRoute));
tracker.Add(() => btn.IsSelected = window.location.hash.Contains(UserPreferencesRecipeView.PreferencesRoute));
sidebar.AddContent(btn);
break;
}
In UserPreferencesRecipeView.cs, the page renders a dropdown for density, a dropdown for default view, and a toggle for onboarding tips. Each control persists immediately to LocalStorage on change.
The route #/recipe/preferences is registered in App.cs next to the rest of the recipe routes.
Where to put the data
| Storage | Use when | API |
|---|---|---|
LocalStorage (used here) |
The setting is per-browser. | LocalStorage.Set("key", value) / LocalStorage.Get("key") |
| Workspace user preferences | The setting should follow the user across devices. | Mosaik.API.User.SettingSaverForUserPreferences() — see Mosaik.FrontEnd.Admin/src/Notifications/Settings/... |
| A custom backend endpoint | The setting affects backend behaviour. | Mosaik.API.Endpoints.CallAsync<T>("recipes/save-preferences", body) — see src/API/Endpoints.cs |
Why the Mode switch matters
The sidebar rebuild callback fires for every sidebar variant (default, admin, user preferences, …). Switching on mode lets you put the right buttons in the right context — admin-only items in admin mode, user-scoped settings in UserPreferences, navigation in Default. See the Sidebar recipe for the default-mode story.
See also
- Sidebar recipe.
Mosaik.FrontEnd/src/Settings/Desktop/PreferencesView.cs— the workspace's own preferences view, much larger but follows exactly this shape.