Overview
Auth Dashboard can be configured through various settings including API endpoints, authentication behavior, theming, and internationalization. This guide covers all configuration options available.
API Configuration
The API client is configured in src/services/api.ts and handles all HTTP requests with automatic token management.
Base Configuration
import axios from "axios" ;
export const api = axios . create ({
baseURL: "https://dummyjson.com" ,
});
By default, the dashboard uses DummyJSON API for demonstration. Replace this with your production API endpoint.
Change API Endpoint
To use your own API, modify the baseURL in src/services/api.ts:
export const api = axios . create ({
baseURL: process . env . VITE_API_URL || "https://api.yourdomain.com" ,
});
Then create a .env file in the project root:
VITE_API_URL = https://api.yourdomain.com
Vite requires environment variables to be prefixed with VITE_ to be exposed to client-side code.
Request Interceptor
The API client automatically injects JWT tokens into all requests:
api . interceptors . request . use (( config ) => {
const token = localStorage . getItem ( "token" );
if ( token ) {
config . headers . Authorization = `Bearer ${ token } ` ;
}
return config ;
});
This interceptor:
Retrieves the token from localStorage
Adds it to the Authorization header
Runs before every API request
Response Interceptor
Automatic error handling for expired tokens:
api . interceptors . response . use (
( response ) => response ,
( error ) => {
if ( error . response ?. status === 401 ) {
localStorage . removeItem ( "token" );
// User will be redirected to login by ProtectedRoute
}
return Promise . reject ( error );
}
);
When a 401 response is received:
Token is removed from localStorage
User state is cleared by Zustand
ProtectedRoute redirects to login page
Authentication Configuration
Token Storage
Tokens are stored in localStorage by default. You can customize this in the auth store:
src/features/auth/authStore.tsx
login : async ( username , password ) => {
const data = await loginRequest ({ username , password });
set ({ user: data , loading: false });
// Store token in localStorage
localStorage . setItem ( "token" , data . token );
}
For enhanced security in production, consider using httpOnly cookies instead of localStorage.
Session Persistence
Zustand persist middleware maintains user sessions across page refreshes:
src/features/auth/authStore.tsx
export const useAuthStore = create < AuthState >()()
persist (
( set ) => ({ /* store implementation */ }),
{
name: "auth-storage" , // localStorage key
}
)
);
Customize Session Key
Change the localStorage key for auth state:
persist (
( set ) => ({ /* store implementation */ }),
{
name: "my-app-auth" , // Custom key name
}
)
Token Expiration
The login request includes a token expiration parameter:
src/features/auth/authService.ts
export const loginRequest = async ({ username , password }) => {
const { data } = await api . post ( "/auth/login" , {
username ,
password ,
expiresInMins: 30 , // Token expires in 30 minutes
});
return {
id: data . id ,
firstName: data . firstName ,
lastName: data . lastName ,
email: data . email ,
image: data . image ,
token: data . accessToken ,
};
};
Adjust expiresInMins based on your security requirements.
Route Configuration
Routes are defined in src/app/router.tsx using React Router v7:
import { createBrowserRouter } from "react-router-dom" ;
export const router = createBrowserRouter ([
{
element: < PublicRoute />,
children: [
{ path: "/login" , element: < Login /> }
],
},
{
element: < ProtectedRoute />,
children: [
{
path: "/" ,
element: < DashboardLayout />,
children: [
{ index: true , element: < Dashboard /> },
{ path: "users" , element: < Users /> },
{ path: "users/:id" , element: < UserDetails /> },
{ path: "settings" , element: < Settings /> },
],
},
],
},
]);
Add New Routes
To add a new protected route:
{
element : < ProtectedRoute />,
children : [
{
path: "/" ,
element: < DashboardLayout />,
children: [
// ... existing routes
{ path: "analytics" , element: < Analytics /> },
],
},
],
}
Custom Redirect Path
Modify the redirect path in ProtectedRoute:
src/app/ProtectedRoute.tsx
import { Navigate , Outlet } from "react-router-dom" ;
import { useAuthStore } from "../features/auth/authStore" ;
const ProtectedRoute = () => {
const user = useAuthStore (( state ) => state . user );
return user ? < Outlet /> : < Navigate to = "/auth/login" replace />;
};
Internationalization
The dashboard supports multiple languages using i18next.
Available Languages
English (en)
Spanish (es)
i18n Configuration
Locale files are located in src/i18n/:
src/i18n/
├── index.ts # i18n configuration
├── en.json # English translations
└── es.json # Spanish translations
Change Default Language
Modify the language in settings store or create an environment variable:
Add New Language
Create Translation File
Create a new JSON file in src/i18n/: {
"common" : {
"login" : "Connexion" ,
"logout" : "Déconnexion"
}
}
Register Language
Import and register in src/i18n/index.ts: import fr from './fr.json' ;
i18n . use ( initReactI18next ). init ({
resources: {
en: { translation: en },
es: { translation: es },
fr: { translation: fr },
},
lng: 'en' ,
fallbackLng: 'en' ,
});
Theme Configuration
The dashboard supports light and dark themes managed through the settings store.
Theme Initialization
Theme is applied in src/AppInitializer.tsx:
import { useEffect } from "react" ;
import { useSettingsStore } from "./shared/store/useSettingsStore" ;
export const AppInitializer = () => {
const theme = useSettingsStore (( store ) => store . theme );
useEffect (() => {
document . documentElement . classList . toggle ( "dark" , theme === "dark" );
}, [ theme ]);
return null ;
};
Set Default Theme
Configure the default theme in your settings store:
const useSettingsStore = create ()()
persist (
( set ) => ({
theme: "light" , // or "dark"
language: "en" ,
}),
{ name: "settings-storage" }
)
);
Environment Variables
Create a .env file for environment-specific configuration:
# API Configuration
VITE_API_URL = https://api.yourdomain.com
VITE_API_TIMEOUT = 10000
# Authentication
VITE_TOKEN_EXPIRY = 30
VITE_SESSION_KEY = auth-storage
# Application
VITE_DEFAULT_LANGUAGE = en
VITE_DEFAULT_THEME = light
# Feature Flags
VITE_ENABLE_ANALYTICS = true
VITE_ENABLE_I18N = true
Never commit .env files with sensitive data to version control. Use .env.example for templates.
Environment-Specific Files
.env # Loaded in all cases
.env.local # Loaded in all cases, ignored by git
.env.development # Loaded in development mode
.env.production # Loaded in production mode
Build Configuration
Vite Configuration
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig ({
plugins: [ react (), tailwindcss ()] ,
server: {
port: 5173 ,
open: true ,
} ,
build: {
outDir: 'dist' ,
sourcemap: true ,
} ,
})
Custom Port
export default defineConfig ({
server: {
port: 3000 ,
} ,
})
TypeScript Configuration
The project uses TypeScript with strict mode enabled:
{
"compilerOptions" : {
"target" : "ES2020" ,
"useDefineForClassFields" : true ,
"lib" : [ "ES2020" , "DOM" , "DOM.Iterable" ],
"module" : "ESNext" ,
"skipLibCheck" : true ,
"moduleResolution" : "bundler" ,
"allowImportingTsExtensions" : true ,
"resolveJsonModule" : true ,
"isolatedModules" : true ,
"noEmit" : true ,
"jsx" : "react-jsx" ,
"strict" : true ,
"noUnusedLocals" : true ,
"noUnusedParameters" : true ,
"noFallthroughCasesInSwitch" : true
}
}
Best Practices
Security
Never commit sensitive data
Use environment variables
Implement HTTPS in production
Rotate tokens regularly
Performance
Enable source maps only in dev
Use code splitting
Optimize bundle size
Cache static assets
Maintainability
Document configuration changes
Use TypeScript for type safety
Follow naming conventions
Keep dependencies updated
Testing
Test with production config
Validate environment variables
Test different locales
Test authentication flows
Next Steps
Authentication Learn about authentication implementation details
API Integration Integrate with your backend API
State Management Understand state management with Zustand
Components Explore the shared component library