Routing
Saucebase uses Laravel's routing system with Inertia.js for seamless SPA navigation. This guide covers how routing works in the modular architecture and how to use Ziggy for client-side routing.
Overview
Saucebase routing combines three key components:
- Laravel Routes - Define server-side endpoints
- Inertia.js - Handle SPA navigation without page reloads
- Ziggy - Access Laravel routes from JavaScript/TypeScript
Defining Routes
Core Application Routes
Core routes are defined in routes/web.php:
// routes/web.php
use Illuminate\Support\Facades\Route;
use Inertia\Inertia;
Route::get('/', function () {
return Inertia::render('Index')->withSSR();
});
Route::get('/dashboard', function () {
return Inertia::render('Dashboard');
})->middleware('auth');
Module Routes
Modules define their own routes in modules/<ModuleName>/routes/web.php:
// modules/Auth/routes/web.php
use Illuminate\Support\Facades\Route;
use Modules\Auth\app\Http\Controllers\AuthController;
Route::prefix('auth')->name('auth.')->group(function () {
Route::get('/login', [AuthController::class, 'showLogin'])->name('login');
Route::post('/login', [AuthController::class, 'login']);
Route::post('/logout', [AuthController::class, 'logout'])->name('logout');
});
Module routes are automatically loaded when the module is enabled.
Inertia Page Resolution
Saucebase extends Inertia's page resolution to support modular architecture with namespace syntax.
Core Pages
Render pages from resources/js/pages/:
// Renders: resources/js/pages/Dashboard.vue
return Inertia::render('Dashboard');
// Renders: resources/js/pages/Settings/Profile.vue
return Inertia::render('Settings/Profile');
Module Pages
Use namespace syntax to render module pages from modules/<ModuleName>/resources/js/pages/:
// Renders: modules/Auth/resources/js/pages/Login.vue
return Inertia::render('Auth::Login');
// Renders: modules/Settings/resources/js/pages/Index.vue
return Inertia::render('Settings::Index');
// Renders: modules/Settings/resources/js/pages/Profile/Edit.vue
return Inertia::render('Settings::Profile/Edit');
Namespace format: ModuleName::PagePath
How It Works
The resolveModularPageComponent() function in resources/js/lib/utils.ts handles page resolution:
- Checks if the page name contains
:: - If yes, extracts module name and page path
- Resolves to:
modules/<Module>/resources/js/pages/<Page>.vue - If no, resolves to:
resources/js/pages/<Page>.vue
Client-Side Routing with Ziggy
Ziggy makes Laravel routes available in JavaScript/TypeScript.
Installation
Ziggy is already configured in Saucebase. Routes are available via the global route() function.
Basic Usage
// Generate URLs
route('dashboard'); // /dashboard
route('settings.profile'); // /settings/profile
// Routes with parameters
route('user.show', { id: 1 }); // /users/1
route('post.show', { post: 42 }); // /posts/42
// Multiple parameters
route('post.comments.show', { post: 1, comment: 5 }); // /posts/1/comments/5
Query Strings
Add query parameters using the _query option:
route('search', {
_query: {
q: 'laravel',
page: 2,
},
}); // /search?q=laravel&page=2
Route Checking
// Check if route exists
route().has('dashboard'); // true/false
// Check current route
route().current(); // 'dashboard'
route().current('dashboard'); // true/false
// Wildcard matching
route().current('settings.*'); // true if on any settings.* route
Navigation with Inertia
Combine Ziggy with Inertia's router for SPA navigation:
<script setup lang="ts">
import { router } from '@inertiajs/vue3';
// Navigate to a route
const goToDashboard = () => {
router.visit(route('dashboard'));
};
// Navigate with method
const deletePost = (id: number) => {
router.delete(route('post.destroy', { post: id }));
};
// Navigate with data
const updateProfile = (data: ProfileData) => {
router.put(route('profile.update'), data);
};
</script>
<template>
<Link :href="route('dashboard')">Dashboard</Link>
<button @click="goToDashboard">Go to Dashboard</button>
</template>
Locale Routing
Saucebase supports multi-language routing with locale prefixes:
// routes/web.php
Route::get('/locale/{locale}', function ($locale) {
if (in_array($locale, ['en', 'pt_BR'])) {
session(['locale' => $locale]);
}
return redirect()->back();
})->name('locale');
Client-side usage:
<script setup lang="ts">
import { router } from '@inertiajs/vue3';
const changeLocale = (locale: string) => {
router.visit(route('locale', { locale }));
};
</script>
<template>
<button @click="changeLocale('en')">English</button>
<button @click="changeLocale('pt_BR')">Português</button>
</template>
Troubleshooting
Routes Not Found (404)
- Clear route cache:
php artisan route:clear - Check module is enabled: Verify
modules_statuses.json - List all routes:
php artisan route:list - Check middleware: Ensure you're authenticated if route requires auth
Ziggy Routes Not Available
- Rebuild assets:
npm run buildor restartnpm run dev - Check Ziggy config:
config/ziggy.php - Verify routes are named: Unnamed routes aren't available in Ziggy
Module Routes Not Loading
- Enable module:
php artisan module:enable <ModuleName> - Clear cache:
php artisan optimize:clear - Check routes file exists:
modules/<ModuleName>/routes/web.php
Inertia Page Not Found
- Check page path: Verify file exists at resolved path
- Rebuild assets: Module pages need
npm run buildafter changes - Check namespace syntax: Use
Module::Pagefor module pages
Next Steps
- Translations - Learn about multi-language support
- SSR - Understand server-side rendering
- Modules - Learn about the Auth module for authentication