Overview
The useSettings hook manages all application settings using Zustand with persistence. It handles API keys, model selection, theming, system prompts, and user preferences with automatic localStorage synchronization.
Import
import { useSettings } from '@/hooks/useSettings';
Usage
const {
apiKey,
selectedModel,
theme,
accent,
systemPrompt,
tone,
notificationsEnabled,
ragEnabled,
hasOnboarded,
setApiKey,
setTheme,
toggleTheme,
toggleSettings,
} = useSettings();
State Properties
OpenRouter API key for authentication. Defaults to empty string.
Currently selected default model ID. Defaults to empty string (user selects during onboarding).
Current UI theme. Defaults to ‘dark’.
accent
'violet' | 'blue' | 'green' | 'rose' | 'orange' | 'teal' | 'red' | 'cyan'
Accent color for the UI. Defaults to ‘violet’.
Custom system prompt for AI conversations. Defaults to empty string.
tone
'neutre' | 'formel' | 'amical' | 'professionnel' | 'enthousiaste'
Conversation tone preference. Defaults to ‘neutre’.
Whether browser notifications are enabled. Defaults to true.
Whether RAG (Retrieval-Augmented Generation) is enabled. Defaults to true.
Whether the user has completed the onboarding flow. Defaults to false.
Whether the settings panel is currently open. Not persisted.
Whether a configuration popup is shown. Not persisted.
Type of configuration popup being displayed. Not persisted.
Setter Methods
setApiKey
Sets the OpenRouter API key.
setApiKey(apiKey: string): void
Example:
const { setApiKey } = useSettings();
setApiKey('sk-or-v1-...');
setSelectedModel
Sets the default model for new conversations.
setSelectedModel(model: string): void
Model ID (e.g., ‘anthropic/claude-3.5-sonnet’).
Example:
const { setSelectedModel } = useSettings();
setSelectedModel('openai/gpt-4-turbo');
setTheme
Sets the UI theme.
setTheme(theme: 'light' | 'dark'): void
Example:
const { setTheme } = useSettings();
setTheme('dark');
setAccent
Sets the accent color.
setAccent(accent: 'violet' | 'blue' | 'green' | 'rose' | 'orange' | 'teal' | 'red' | 'cyan'): void
Example:
const { setAccent } = useSettings();
setAccent('blue');
setSystemPrompt
Sets the system prompt for AI conversations.
setSystemPrompt(systemPrompt: string): void
Custom system instruction for the AI.
Example:
const { setSystemPrompt } = useSettings();
setSystemPrompt('You are a helpful coding assistant specializing in React.');
setTone
Sets the conversation tone.
setTone(tone: 'neutre' | 'formel' | 'amical' | 'professionnel' | 'enthousiaste'): void
Example:
const { setTone } = useSettings();
setTone('professionnel');
setNotificationsEnabled
Enables or disables browser notifications.
setNotificationsEnabled(enabled: boolean): void
Whether to enable notifications.
setRagEnabled
Enables or disables RAG (Retrieval-Augmented Generation).
setRagEnabled(enabled: boolean): void
Example:
const { setRagEnabled } = useSettings();
setRagEnabled(true); // Enable context retrieval
setHasOnboarded
Marks the user as having completed onboarding.
setHasOnboarded(hasOnboarded: boolean): void
Whether onboarding is complete.
Shows or hides a configuration popup.
setShowConfigurationPopup(show: boolean, type?: 'missing-api-key' | 'configuration-error'): void
Whether to show the popup.
type
'missing-api-key' | 'configuration-error'
Type of popup to display.
Example:
const { setShowConfigurationPopup } = useSettings();
// Show API key missing popup
setShowConfigurationPopup(true, 'missing-api-key');
// Hide popup
setShowConfigurationPopup(false);
Toggle Methods
toggleTheme
Toggles between light and dark theme.
Example:
const { theme, toggleTheme } = useSettings();
return (
<button onClick={toggleTheme}>
{theme === 'light' ? '🌙' : '☀️'}
</button>
);
toggleSettings
Toggles the settings panel open/closed.
closeSettings
Closes the settings panel.
Types
Settings
interface Settings {
apiKey: string;
selectedModel: string;
theme: 'light' | 'dark';
accent?: 'violet' | 'blue' | 'green' | 'rose' | 'orange' | 'teal' | 'red' | 'cyan';
systemPrompt: string;
tone?: 'neutre' | 'formel' | 'amical' | 'professionnel' | 'enthousiaste';
notificationsEnabled?: boolean;
ragEnabled?: boolean;
hasOnboarded?: boolean;
}
Default Values
const DEFAULT_SETTINGS: Settings = {
apiKey: '',
selectedModel: '',
theme: 'dark',
accent: 'violet',
systemPrompt: '',
tone: 'neutre',
notificationsEnabled: true,
ragEnabled: true,
hasOnboarded: false,
};
Persistence
Settings are automatically persisted to localStorage using Zustand’s persist middleware:
persist(
(set, get) => ({ /* store */ }),
{ name: 'polychat-settings' }
)
Storage key: polychat-settings
Integration with useChat
The useChat hook subscribes to selectedModel changes to update temporary sessions:
useSettings.subscribe((state, prevState) => {
if (state.selectedModel !== prevState?.selectedModel) {
// Update temporary session model
}
});
Example: Settings Panel
import { useSettings } from '@/hooks/useSettings';
function SettingsPanel() {
const {
apiKey,
theme,
accent,
systemPrompt,
tone,
ragEnabled,
setApiKey,
toggleTheme,
setAccent,
setSystemPrompt,
setTone,
setRagEnabled,
} = useSettings();
return (
<div>
<h2>Settings</h2>
<label>
API Key:
<input
type="password"
value={apiKey}
onChange={(e) => setApiKey(e.target.value)}
placeholder="sk-or-v1-..."
/>
</label>
<button onClick={toggleTheme}>
Theme: {theme}
</button>
<label>
Accent Color:
<select value={accent} onChange={(e) => setAccent(e.target.value)}>
<option value="violet">Violet</option>
<option value="blue">Blue</option>
<option value="green">Green</option>
<option value="rose">Rose</option>
</select>
</label>
<label>
System Prompt:
<textarea
value={systemPrompt}
onChange={(e) => setSystemPrompt(e.target.value)}
placeholder="Custom instructions for the AI..."
/>
</label>
<label>
Tone:
<select value={tone} onChange={(e) => setTone(e.target.value)}>
<option value="neutre">Neutre</option>
<option value="formel">Formel</option>
<option value="amical">Amical</option>
<option value="professionnel">Professionnel</option>
<option value="enthousiaste">Enthousiaste</option>
</select>
</label>
<label>
<input
type="checkbox"
checked={ragEnabled}
onChange={(e) => setRagEnabled(e.target.checked)}
/>
Enable RAG (Context Retrieval)
</label>
</div>
);
}
Example: Onboarding Flow
import { useSettings } from '@/hooks/useSettings';
import { useModels } from '@/hooks/useModels';
function Onboarding() {
const { hasOnboarded, setApiKey, setSelectedModel, setHasOnboarded } = useSettings();
const { models } = useModels();
const [key, setKey] = useState('');
const [model, setModel] = useState('');
if (hasOnboarded) return null;
const handleComplete = () => {
setApiKey(key);
setSelectedModel(model);
setHasOnboarded(true);
};
return (
<div>
<h1>Welcome to PolyChat-AI</h1>
<input
type="password"
placeholder="OpenRouter API Key"
value={key}
onChange={(e) => setKey(e.target.value)}
/>
<select value={model} onChange={(e) => setModel(e.target.value)}>
<option value="">Select a model...</option>
{models.map((m) => (
<option key={m.id} value={m.id}>
{m.name || m.id}
</option>
))}
</select>
<button onClick={handleComplete} disabled={!key || !model}>
Get Started
</button>
</div>
);
}