Laravel + Next.js: Architecture for Full Stack Applications
How to structure a Laravel backend with a Next.js frontend for production applications, covering API design, authentication flow, and deployment strategies.
The Laravel + Next.js Stack
Laravel handles the backend logic, API, database, and authentication. Next.js handles the frontend rendering, routing, and user interface. Together, they give you a powerful full stack setup.
I've used this architecture for healthcare platforms and business applications where both performance and developer experience matter.
Project Structure
project/
├── backend/ # Laravel API
│ ├── app/
│ ├── routes/
│ └── ...
├── frontend/ # Next.js app
│ ├── app/
│ ├── components/
│ ├── lib/
│ └── ...
└── docker-compose.ymlAPI Design
Keep your Laravel API focused on data and business logic:
// Backend: routes/api.php
Route::prefix('v1')->group(function () {
Route::post('login', [AuthController::class, 'login']);
Route::post('register', [AuthController::class, 'register']);
Route::middleware('auth:api')->group(function () {
Route::apiResource('patients', PatientController::class);
Route::apiResource('appointments', AppointmentController::class);
});
});Frontend API Layer
Create a clean API layer in Next.js:
// lib/api.ts
const API_BASE = process.env.NEXT_PUBLIC_API_URL;
async function apiFetch<T>(endpoint: string, options?: RequestInit): Promise<T> {
const token = localStorage.getItem('token');
const response = await fetch(`${API_BASE}/api/v1${endpoint}`, {
...options,
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
...(token ? { Authorization: `Bearer ${token}` } : {}),
...options?.headers,
},
});
if (!response.ok) {
throw new ApiError(response.status, await response.json());
}
return response.json();
}
export const api = {
get: <T>(endpoint: string) => apiFetch<T>(endpoint),
post: <T>(endpoint: string, data: unknown) =>
apiFetch<T>(endpoint, { method: 'POST', body: JSON.stringify(data) }),
};Authentication Flow
1. User submits credentials to Next.js form
2. Next.js sends POST to Laravel /api/v1/login
3. Laravel returns JWT token
4. Next.js stores token in localStorage
5. Subsequent requests include Authorization: Bearer <token> header
CORS Configuration
Laravel needs to allow requests from your Next.js dev server:
// config/cors.php
'allowed_origins' => [
'http://localhost:3000',
'https://your-domain.com',
],