Step 5 — Wiring & Backend¶
Guide: Customizing Your Frontend · Step 5 of 5
Live: https://docs.mozaiks.ai/guides/custom-frontend/wiring.html
App config — app.json¶
All identity and connection config lives in one shared file at templates/app.json:
{
"appName": "My App",
"appId": "my-app",
"defaultWorkflow": "hello_world",
"apiUrl": "http://localhost:8000"
}
App.jsx imports this file directly — no hard-coded values anywhere else:
import { MozaiksApp, mockApiAdapter } from '@mozaiks/chat-ui';
import appConfig from '../app.json';
export default function App() {
return (
<MozaiksApp
appName={appConfig.appName}
defaultAppId={appConfig.appId}
defaultWorkflow={appConfig.defaultWorkflow}
apiAdapter={mockApiAdapter}
/>
);
}
Swapping in a real API adapter¶
Swap mockApiAdapter for a real one once your backend is running:
import { MozaiksApp, RestApiAdapter } from '@mozaiks/chat-ui';
import appConfig from '../app.json';
const apiAdapter = new RestApiAdapter({
baseUrl: appConfig.apiUrl,
getAuthToken: async () => await auth.currentUser.getIdToken(),
});
export default function App() {
return (
<MozaiksApp
appName={appConfig.appName}
defaultAppId={appConfig.appId}
defaultWorkflow={appConfig.defaultWorkflow}
apiAdapter={apiAdapter}
/>
);
}
MozaiksApp prop | Type | Description |
|---|---|---|
appName | string | Display name shown in the header |
defaultAppId | string | App identifier sent to the backend |
defaultWorkflow | string | Workflow to activate on load |
apiAdapter | object | Implement listGeneralChats, sendMessage, etc. |
authAdapter | object optional | Plugs into your auth provider |
uiConfig | object optional | Full config override (replaces individual props) |
The onAction contract¶
Header and profile dropdown actions dispatch through onAction(action, item) inside ChatPage.
Handle them in the handleHeaderAction function:
function handleHeaderAction(action, item) {
switch (action) {
case 'navigate':
navigate(item.href);
break;
case 'signout':
authAdapter.signOut();
break;
case 'discover':
navigate('/discover');
break;
default:
console.warn('[onAction] Unhandled action:', action, item);
}
}
The action string comes directly from the "action" field of the item in ui.json.
User context¶
Pass a user object to MozaiksApp via authAdapter or directly when authenticated:
const user = {
id: 'user_abc123',
firstName: 'Maya',
userPhoto: 'https://…/photo.jpg', // null if no photo
email: 'maya@yourapp.com',
};
Avatar render priority¶
user.userPhoto— when present and loads successfully- Generated initials — derived from
user.firstNameon photo failure - Fallback icon — the
profile.iconSVG fromui.json
Auth provider integration¶
Map your provider's user object to { id, firstName, userPhoto }:
import { useAuthState } from 'react-firebase-hooks/auth';
import { auth } from './firebase';
import { MozaiksApp, RestApiAdapter } from '@mozaiks/chat-ui';
import appConfig from '../app.json';
const apiAdapter = new RestApiAdapter({ baseUrl: appConfig.apiUrl });
export function App() {
const [firebaseUser] = useAuthState(auth);
const user = firebaseUser
? {
id: firebaseUser.uid,
firstName: firebaseUser.displayName,
userPhoto: firebaseUser.photoURL,
email: firebaseUser.email,
}
: null;
return (
<MozaiksApp
appName={appConfig.appName}
defaultAppId={appConfig.appId}
defaultWorkflow={appConfig.defaultWorkflow}
apiAdapter={apiAdapter}
/>
);
}
Works with any provider: Supabase, Clerk, Auth0, custom JWT.
Custom action names¶
Any string in "action" fields is forwarded to your handler as-is:
{ "id": "open-feedback", "label": "Send Feedback", "icon": "feedback.svg", "action": "open-feedback" }
Prev: Step 4 — Assets & Icons
Back to index: Customizing Your Frontend