Skip to main content
The frontend is built with Vue 3, Inertia.js, TypeScript, and Tailwind CSS 4, providing a modern, type-safe, and reactive user interface.

Tech Stack

Vue 3

Composition API, TypeScript support, and reactive state management

Inertia.js

Server-side routing with SPA-like experience, no separate API needed

Tailwind CSS 4

Utility-first CSS with custom design system

TypeScript

Type safety for Vue components and application logic

Project Structure

The frontend code lives in resources/js/:

Inertia.js Architecture

Inertia.js bridges Laravel and Vue without building a separate API. Controllers return Inertia responses that render Vue components.

How It Works

1

Controller Returns Data

Laravel controller returns an Inertia response with page component and props:
app/Http/Controllers/System/DashboardController.php
2

Vue Component Receives Props

The Vue component receives the data as typed props:
resources/js/pages/system/Dashboard.vue
3

Navigation Updates Without Full Reload

Inertia intercepts links and form submissions, making XHR requests and swapping components:

Benefits of Inertia

Controllers return data directly to Vue components. No need to build REST or GraphQL APIs.
Routes are defined in Laravel. No need to sync frontend and backend route definitions.
Generate type-safe route helpers from Laravel routes:
Share data across all pages via middleware:

Vue Components

Component Structure

Components follow the Composition API with <script setup> syntax:
resources/js/components/AppHeader.vue

UI Component Library

The project uses shadcn-vue components located in resources/js/components/ui/:

Available Components

Layout

Card, Sheet, Tabs, Separator, Accordion

Forms

Input, Textarea, Select, Checkbox, Radio, Switch

Feedback

Alert, Toast, Dialog, Popover, Tooltip

Navigation

Breadcrumb, Dropdown Menu, Navigation Menu

Data Display

Table, Badge, Avatar, Calendar

Controls

Button, Command, Context Menu, Slider

Layouts

Layouts provide consistent structure across pages:

AppLayout (System)

resources/js/layouts/AppLayout.vue

Usage in Pages

resources/js/pages/system/Dashboard.vue

Composables

Reusable logic extracted into composables (Vue’s equivalent of React hooks):

useAppearance

resources/js/composables/useAppearance.ts

useTwoFactorAuth

resources/js/composables/useTwoFactorAuth.ts

Tailwind CSS

The project uses Tailwind CSS 4 with custom configuration:

Configuration

vite.config.ts

Utility Classes

Custom Utilities

Use clsx and tailwind-merge for conditional classes:
resources/js/lib/utils.ts

Form Handling

Inertia provides a useForm helper for managing form state:
resources/js/pages/system/tenants/Create.vue

Form Features

  • Automatic CSRF protection: Handled by Inertia
  • Validation errors: Automatically populated in form.errors
  • Loading states: Track submission with form.processing
  • Optimistic updates: Update UI before server response
  • File uploads: Support for multipart/form-data

TypeScript

The project uses TypeScript for type safety:
resources/js/types/index.ts

Type-Safe Props

Build Configuration

Vite powers the frontend build process:
vite.config.ts

Development

Production Build

SSR Build

Best Practices

  • Keep components small and focused
  • Use composition API with <script setup>
  • Extract reusable logic into composables
  • Define TypeScript interfaces for props
  • Use local state with ref() and reactive()
  • Share state across components with composables
  • Use Inertia’s shared data for global state
  • Avoid prop drilling with provide/inject
  • Use v-memo for expensive renders
  • Lazy load routes with dynamic imports
  • Optimize images with proper sizing
  • Use <Suspense> for async components
  • Define interfaces for all props
  • Use TypeScript for composables
  • Type Inertia page props
  • Enable strict mode in tsconfig.json

Next Steps

Backend Development

Learn about Laravel controllers and services

Testing

Write tests for Vue components and pages