Building a Dynamic Vue Frontend for Laravel SaaS
Discover how to design an adaptable Vue frontend for a multi-tenant Laravel SaaS application using Inertia v2. This guide dives into essential aspects like layout switching, overlay systems, pagination, and testing, all while avoiding complex state management.
The Challenge
Creating a multi-tenant SaaS requires distinct layouts for different user roles. For instance, at Kohana.io, five unique layouts were needed:
- GuestLayout: For non-logged-in users, featuring landing pages and login modals.
- AuthLayout: For regular users, includes app headers and notifications.
- AdminLayout: For admin users, offering an admin panel with special navigation.
- AuthBlockedLayout: For blocked accounts, limited to support tickets.
- AuthDeletedLayout: For deleted accounts, minimal UI for data requests.
Each layout demands a unique component structure, and Inertia's persistent layouts ensure they remain mounted across navigation.
Architectural Blueprint
The architecture begins with the HandleInertiaRequests middleware, determining visitor status and lazy-loading layout data. The frontend's entry point in app.js sets up Inertia and plugins, leading to the LayoutSwitcher component, which renders the correct layout based on the visitor status.
LayoutSwitcher Pattern
The LayoutSwitcher.vue script reads the visitor status and renders the corresponding layout component without Vue-specific auth checks or route guards.
<script setup>
import { computed } from 'vue';
import { usePage } from '@inertiajs/vue3';
...
const visitorStatus = computed(() => usePage().props.visitor_status);
</script>
Overlay System
A robust SaaS layout involves more than headers and sidebars. The authenticated layout in Kohana.io features seven pullout panels, which can stack and manage overlays independently.
State Management
Reactive refs manage overlay states without a state library:
const viewPulloutMobilemenu = ref(false);
...
Pagination and Filtering
The backend leverages a HasPagination trait to manage pagination data, ensuring filters are preserved through withQueryString().
PagePaginator Component
Located in the layout, this component auto-renders pagination links while maintaining query parameters, utilizing Inertia's <Link> for SPA navigation.
Filtering System
Filters employ method auto-discovery, allowing request parameters to dynamically invoke filter methods.
abstract class Filter {...}
Modal and Popup Management
LaraFoundry's modals utilize custom components for complex interactions and SweetAlert2 for confirmations, ensuring efficient UI handling.
Testing Strategies
Frontend behavior is verified through Pest feature tests that assert on Inertia props, ensuring accurate layout switching, pagination, and filter functionality.
Conclusion
The approach emphasizes pushing complexity to the backend, allowing Vue to focus on rendering pre-computed data. This method streamlines the front-end development process and enhances user experience.
LaraFoundry, an open-source Laravel SaaS framework, exemplifies these principles in a real-world application.