Skip to Content
FrontendAppsAccountUser Preferences

User Preferences

This document describes how user preferences (theme, locale, timezone) are read and written across the frontend apps, using the shared auth bundle. It replaces the information originally shared ad-hoc in phpreaction-frontend-account-crud-react-v2#6 , verified and updated against the actual implementation in phpreaction-frontend-account-react.

Overview

user_preferences is part of the User object returned by getUserInformations() (@phpcreation/frontend-auth-authorization-flow-react-nextjs-bundle). Any app that renders a UserProvider with that user gets read access to preferences through useUser(), anywhere in the component tree. Writing preferences goes through the Account API and is only implemented in the account app today.

Reading preferences

1. Fetch the user server-side (layout)

import { getUserInformations } from "@phpcreation/frontend-auth-authorization-flow-react-nextjs-bundle/utils"; const user = await getUserInformations( tenant?.name || "demo1", true, // getGravatar undefined, // idToken — auto-read from the id_token cookie server-side undefined, // userToken — auto-read from the currentUser cookie server-side true, // getFromCache );

2. Wrap the app with UserProvider

import { UserProvider } from "@phpcreation/frontend-auth-authorization-flow-react-nextjs-bundle/contexts"; <UserProvider user={user}>{children}</UserProvider>;

3. Read user_preferences anywhere with useUser()

import { useUser } from "@phpcreation/frontend-auth-authorization-flow-react-nextjs-bundle/contexts"; const { user } = useUser(); user?.user_preferences?.theme; // "light" | "dark" | "system" user?.user_preferences?.locale; // "fr" | "en" user?.user_preferences?.timezone; // e.g. "America/New_York"

user_preferences can be empty/undefined for a given key — always provide a fallback (theme defaults to "system", locale to "fr", timezone to the browser’s guessed timezone).

Real usage in phpreaction-frontend-account-react

WhereWhat it reads
src/app/[locale]/layout.tsxuser_preferences.theme — passed as ThemeProvider’s defaultTheme
src/components/LayoutClient/index.tsxuser_preferences.locale / .timezone — passed to the Footer
src/hooks/usePreferences.tsxall three, as the form’s defaultValues

Writing preferences

Only the account app currently exposes a form to update preferences (/[locale]/preferences). Other apps should read via useUser() but should not attempt to write preferences themselves — send users to the account app’s preferences page instead.

Form → hook → server action → API

// src/hooks/usePreferences.tsx const handleSubmit = async (data) => { const newData = { preferences: { theme: data.theme, locale: data.locale, timezone: data.timezone, }, }; const preferences = await editUserPreferences(tenant, newData); if (preferences.ok) { setTheme(data.theme); await getNewUser(tenant, true); // refresh the UserProvider's context router.replace(`/${data.locale}`); } };
// src/app/[locale]/preferences/actions.ts export async function editUserPreferences(tenant, body) { await checkRequireAuth(); return callAccountApi( "PATCH", tenant, "users/preferences/update", "", JSON.stringify(body), true, ); }

The endpoint is PATCH /api/v1/users/preferences/update. An earlier version of this documentation (and of the API Calls page) referenced PATCH /api/v1/users/{id}/preferences, which does not match the current implementation — that reference has been corrected.

After a successful save, getNewUser(tenant, true) is called to force-refresh the UserProvider context so the rest of the app immediately reflects the new preferences (no full reload needed), then the user is redirected to the new locale’s URL.

Last updated on