Skip to main content

Get Started in 5 Minutes

This guide will help you set up and run the Auth Dashboard locally. You’ll learn how to install dependencies, configure the application, and implement authentication.

Prerequisites

Before you begin, ensure you have:
  • Node.js 18+ installed on your machine
  • npm, yarn, or pnpm package manager
  • A code editor (VS Code recommended)
  • Basic knowledge of React and TypeScript

Setup Steps

1

Clone and Install

First, navigate to your project directory and install dependencies:
npm install
This installs all required packages including React, TypeScript, Zustand, and Axios.
2

Start the Development Server

Run the development server:
npm run dev
The application will start at http://localhost:5173 (default Vite port).
3

Access the Login Page

Open your browser and navigate to http://localhost:5173/login. You’ll see the login interface.
The dashboard uses DummyJSON API for demonstration. Use the default credentials: emilys / emilyspass
4

Implement Authentication

The authentication system is already configured. Here’s how it works:
src/features/auth/authStore.tsx
import { create } from "zustand";
import { persist } from "zustand/middleware";
import { loginRequest } from "./authService";

export const useAuthStore = create<AuthState>()()
  persist(
    (set) => ({
      user: null,
      loading: false,

      login: async (username, password) => {
        try {
          set({ loading: true });
          const data = await loginRequest({ username, password });
          set({ user: data, loading: false });
          localStorage.setItem("token", data.token);
        } catch (error) {
          set({ loading: false });
          console.error(error);
        }
      },

      logout: () => {
        localStorage.removeItem("token");
        set({ user: null });
      },
    }),
    { name: "auth-storage" }
  )
);
The store uses Zustand with persistence to maintain user sessions across page refreshes.
5

Use Authentication in Components

Access authentication state and methods in any component:
src/pages/Login.tsx
import { useAuthStore } from "../features/auth/authStore";
import { useNavigate } from "react-router-dom";

export default function Login() {
  const login = useAuthStore((state) => state.login);
  const loading = useAuthStore((state) => state.loading);
  const navigate = useNavigate();

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    await login(username, password);
    
    if (useAuthStore.getState().user) {
      navigate("/", { replace: true });
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      {/* Form fields */}
    </form>
  );
}
6

Protect Your Routes

Use the built-in ProtectedRoute component to secure routes:
src/app/router.tsx
import { createBrowserRouter } from "react-router-dom";
import ProtectedRoute from "./ProtectedRoute";
import { DashboardLayout } from "../shared/layout/DashboardLayout";

export const router = createBrowserRouter([
  {
    element: <ProtectedRoute />,
    children: [
      {
        path: "/",
        element: <DashboardLayout />,
        children: [
          { index: true, element: <Dashboard /> },
          { path: "users", element: <Users /> },
          { path: "settings", element: <Settings /> },
        ],
      },
    ],
  },
]);
The ProtectedRoute automatically redirects unauthenticated users to /login:
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="/login" replace />;
};

Test the Authentication

You can now test the complete authentication flow:
  1. Navigate to http://localhost:5173/login
  2. Enter credentials: emilys / emilyspass
  3. Click “Login” - you’ll be redirected to the dashboard
  4. Try accessing protected routes - they’ll work!
  5. Refresh the page - your session persists
  6. Logout and try accessing protected routes - you’ll be redirected to login
The application uses DummyJSON API (https://dummyjson.com) for backend services. In production, replace this with your own API.

API Configuration

The API client is configured in src/services/api.ts with automatic token injection:
src/services/api.ts
import axios from "axios";

export const api = axios.create({
  baseURL: "https://dummyjson.com",
});

// Automatically inject tokens
api.interceptors.request.use((config) => {
  const token = localStorage.getItem("token");
  if (token) {
    config.headers.Authorization = `Bearer ${token}`;
  }
  return config;
});

// Handle 401 errors
api.interceptors.response.use(
  (response) => response,
  (error) => {
    if (error.response?.status === 401) {
      localStorage.removeItem("token");
    }
    return Promise.reject(error);
  }
);

What’s Next?

Configuration

Learn how to configure the API endpoint and other settings

Authentication Guide

Deep dive into the authentication system

User Management

Explore user CRUD operations

Routing

Learn about protected routes and navigation

Common Issues

If port 5173 is already in use, Vite will automatically try the next available port. Check your terminal output for the actual port.
Ensure you have an active internet connection. The app uses DummyJSON API which requires internet access.
Check your browser’s localStorage settings. The app uses localStorage for session persistence.

Build docs developers (and LLMs) love