Overview
Laravel Breeze API + Next.js uses a monorepo structure that separates the backend and frontend into distinct directories while keeping them in a single repository. This approach provides clear separation of concerns while maintaining ease of development.
Repository Structure
LaravelBreezeApi_Nextjs/
├── Backend/ # Laravel 12 API
│ ├── app/
│ ├── bootstrap/
│ ├── config/
│ ├── database/
│ ├── public/
│ ├── resources/
│ ├── routes/
│ ├── storage/
│ ├── tests/
│ ├── .env.example
│ ├── artisan
│ ├── composer.json
│ └── phpunit.xml
│
├── Frontend/ # Next.js 16 Application
│ ├── public/
│ ├── src/
│ ├── .env.example
│ ├── next.config.js
│ ├── package.json
│ ├── tailwind.config.ts
│ └── tsconfig.json
│
├── .editorconfig
├── .git/
├── CONTRIBUTING.md
├── LICENSE.md
└── README.md
Backend Structure (Laravel)
Core Directories
Contains the core application code including controllers, models, and middleware. app/
├── Http/
│ ├── Controllers/
│ │ ├── Auth/ # Authentication controllers
│ │ │ ├── AuthenticatedSessionController.php
│ │ │ ├── EmailVerificationNotificationController.php
│ │ │ ├── NewPasswordController.php
│ │ │ ├── PasswordResetLinkController.php
│ │ │ ├── RegisteredUserController.php
│ │ │ └── VerifyEmailController.php
│ │ └── Controller.php # Base controller
│ ├── Middleware/
│ │ └── EnsureEmailIsVerified.php # Email verification middleware
│ └── Requests/
│ └── Auth/
│ └── LoginRequest.php # Login validation request
├── Models/
│ └── User.php # User Eloquent model
└── Providers/
└── AppServiceProvider.php # Application service provider
Defines all API endpoints and authentication routes. routes/
├── api.php # Protected API routes (requires auth:sanctum)
├── auth.php # Authentication routes (register, login, logout)
├── console.php # Artisan console commands
└── web.php # Web routes (minimal for API-only)
api.php - Protected API routes:Route :: middleware ([ 'auth:sanctum' ]) -> get ( '/user' , function ( Request $request ) {
return $request -> user ();
});
auth.php - Authentication endpoints:Route :: post ( '/register' , [ RegisteredUserController :: class , 'store' ])
-> middleware ( 'guest' );
Route :: post ( '/login' , [ AuthenticatedSessionController :: class , 'store' ])
-> middleware ( 'guest' );
Route :: post ( '/logout' , [ AuthenticatedSessionController :: class , 'destroy' ])
-> middleware ( 'auth' );
config/ - Configuration Files
Contains all Laravel configuration files. config/
├── app.php # Application settings
├── auth.php # Authentication configuration
├── cache.php # Cache configuration
├── cors.php # CORS settings for API
├── database.php # Database connections
├── filesystems.php # File storage configuration
├── logging.php # Logging configuration
├── mail.php # Email configuration
├── queue.php # Queue configuration
├── sanctum.php # Sanctum authentication config
├── services.php # Third-party services
└── session.php # Session configuration
Key Configuration: cors.php return [
'paths' => [ '*' ],
'allowed_methods' => [ '*' ],
'allowed_origins' => [ env ( 'FRONTEND_URL' , 'http://localhost:3000' )],
'supports_credentials' => true ,
];
database/ - Database Management
Contains migrations, seeders, and factories for database management. database/
├── factories/
│ └── UserFactory.php # User model factory
├── migrations/
│ ├── 0001_01_01_000000_create_users_table.php # Users table
│ ├── 0001_01_01_000001_create_cache_table.php # Cache table
│ ├── 0001_01_01_000002_create_jobs_table.php # Queue jobs table
│ └── 2026_02_06_051602_create_personal_access_tokens_table.php
└── seeders/
└── DatabaseSeeder.php # Main seeder
Contains feature and unit tests using Pest PHP. tests/
├── Feature/
│ ├── Auth/
│ │ ├── AuthenticationTest.php
│ │ ├── EmailVerificationTest.php
│ │ ├── PasswordResetTest.php
│ │ └── RegistrationTest.php
│ └── ExampleTest.php
├── Unit/
│ └── ExampleTest.php
├── Pest.php # Pest configuration
└── TestCase.php # Base test case
Contains application-generated files, logs, and cached data. storage/
├── app/ # Application files
├── framework/ # Framework cache and sessions
│ ├── cache/
│ ├── sessions/
│ └── views/
└── logs/ # Application logs
└── laravel.log
bootstrap/ - Application Bootstrap
Contains application bootstrap and caching files. bootstrap/
├── app.php # Application bootstrap
├── cache/ # Bootstrap cache
└── providers.php # Service providers cache
Key Backend Files
composer.json
.env.example
{
"name" : "laravel/laravel" ,
"type" : "project" ,
"description" : "Laravel Breeze API with Sanctum authentication" ,
"require" : {
"php" : "^8.2" ,
"laravel/framework" : "^12.0" ,
"laravel/sanctum" : "^4.0" ,
"laravel/tinker" : "^2.9"
},
"require-dev" : {
"laravel/breeze" : "^2.0" ,
"pestphp/pest" : "^3.0" ,
"pestphp/pest-plugin-laravel" : "^3.0"
}
}
Frontend Structure (Next.js)
Core Directories
Next.js 16 App Router structure with route groups and layouts. src/app/
├── (authenticated)/ # Protected routes group
│ ├── dashboard/
│ │ └── page.tsx # Dashboard page
│ └── layout.tsx # Authenticated layout with navigation
│
├── (guest)/ # Guest routes group
│ ├── forgot-password/
│ │ └── page.tsx # Forgot password page
│ ├── login/
│ │ └── page.tsx # Login page
│ ├── password-reset/
│ │ └── [token]/
│ │ └── page.tsx # Password reset page
│ └── register/
│ └── page.tsx # Registration page
│
├── favicon.ico # Application favicon
├── globals.css # Global styles
├── layout.tsx # Root layout
├── not-found.tsx # 404 page
└── page.tsx # Home page
Route groups (authenticated) and (guest) organize routes without affecting the URL structure.
src/components/ - React Components
Reusable React components organized by feature. src/components/
└── Layouts/
├── Navigation.tsx # Main navigation component
├── GuestLayout.tsx # Guest layout wrapper
└── AppLayout.tsx # Authenticated app layout
src/hooks/ - Custom Hooks
Custom React hooks for authentication and data fetching. src/hooks/
└── auth.ts # useAuth hook for authentication
useAuth Hook :export const useAuth = ({
middleware ,
redirectIfAuthenticated ,
} : {
middleware ?: string
redirectIfAuthenticated ?: string
}) => {
// SWR for user data fetching
const { data : user , error , mutate } = useSWR ( '/api/user' , ... )
return {
user ,
register ,
login ,
forgotPassword ,
resetPassword ,
resendEmailVerification ,
logout ,
}
}
src/lib/ - Utilities & Configuration
Library code, utilities, and API client configuration. src/lib/
└── axios.ts # Axios instance with base configuration
Axios Configuration :const axios : AxiosInstance = Axios . create ({
baseURL: process . env . NEXT_PUBLIC_BACKEND_URL ,
headers: {
'X-Requested-With' : 'XMLHttpRequest' ,
},
withCredentials: true ,
withXSRFToken: true ,
})
src/types/ - TypeScript Types
TypeScript type definitions and interfaces. src/types/
└── index.ts # Shared type definitions
Static files served directly by Next.js. public/
├── images/
├── icons/
└── favicon.ico
Key Frontend Files
package.json
tsconfig.json
.env.example
{
"name" : "laravel-breeze-nextjs" ,
"version" : "1.0.0" ,
"private" : true ,
"scripts" : {
"dev" : "next dev" ,
"build" : "next build" ,
"start" : "next start" ,
"lint" : "next lint"
},
"dependencies" : {
"react" : "^18" ,
"react-dom" : "^18" ,
"next" : "^16" ,
"axios" : "^1.6.0" ,
"swr" : "^2.2.0" ,
"formik" : "^2.4.0" ,
"yup" : "^1.3.0"
},
"devDependencies" : {
"typescript" : "^5" ,
"@types/node" : "^20" ,
"@types/react" : "^18" ,
"tailwindcss" : "^3.4.0" ,
"eslint" : "^8" ,
"eslint-config-next" : "^16"
}
}
Route Groups Explained
Authenticated Routes (authenticated)/
Routes that require user authentication:
src/app/(authenticated)/layout.tsx
'use client'
import { ReactNode } from 'react'
import { useAuth } from '@/hooks/auth'
import Navigation from '@/components/Layouts/Navigation'
const AppLayout = ({ children } : { children : ReactNode }) => {
const { user } = useAuth ({ middleware: 'auth' })
return (
< div className = "min-h-screen bg-gray-100" >
< Navigation user = { user } />
< main > { children } </ main >
</ div >
)
}
export default AppLayout
The middleware: 'auth' parameter in the useAuth hook automatically redirects unauthenticated users to the login page.
Guest Routes (guest)/
Routes accessible only to unauthenticated users (login, register, etc.):
/login - User login
/register - User registration
/forgot-password - Password reset request
/password-reset/[token] - Password reset form
Guest routes automatically redirect authenticated users to the dashboard.
Development Workflow
Running the Application
Combined (Recommended)
Separate Terminals
Run both backend and frontend together from the Backend directory: cd Backend
composer run dev
This executes:
Laravel development server (php artisan serve)
Queue worker (php artisan queue:listen)
Next.js development server (npm run dev)
Terminal 1 - Backend: cd Backend
php artisan serve
Terminal 2 - Frontend: cd Frontend
npm run dev
# or
pnpm dev
File Organization Best Practices
Controllers Backend : Keep controllers thin, delegate to servicesapp / Http / Controllers /
app / Services /
Components Frontend : Organize by feature or domainsrc / components / Auth /
src / components / Dashboard /
src / components / Layouts /
Business Logic Backend : Use service classes and actionsapp / Services /
app / Actions /
Shared Types Frontend : Define shared types centrallysrc / types / models . ts
src / types / api . ts
Configuration Files
Backend Configuration
Defines PHP dependencies and scripts. {
"scripts" : {
"dev" : "concurrently \" php artisan serve \" \" php artisan queue:listen \" \" npm --prefix ../Frontend run dev \" " ,
"test" : "pest"
}
}
Environment-specific configuration. APP_URL=http://localhost:8000
FRONTEND_URL=http://localhost:3000
SANCTUM_STATEFUL_DOMAINS=localhost,localhost:3000
Frontend Configuration
next.config.js
tailwind.config.ts
Next.js configuration. module . exports = {
reactStrictMode: true ,
images: {
domains: [ 'localhost' ],
},
}
Tailwind CSS configuration. export default {
content: [
'./src/pages/**/*.{js,ts,jsx,tsx,mdx}' ,
'./src/components/**/*.{js,ts,jsx,tsx,mdx}' ,
'./src/app/**/*.{js,ts,jsx,tsx,mdx}' ,
] ,
theme: {
extend: {},
} ,
plugins: [] ,
}
Adding New Features
Backend: Adding a New API Endpoint
Create Controller
php artisan make:controller Api/PostController --api
Define Route
Route :: middleware ([ 'auth:sanctum' ]) -> group ( function () {
Route :: apiResource ( 'posts' , PostController :: class );
});
Create Model & Migration
php artisan make:model Post -m
Frontend: Adding a New Page
Create Page File
# For authenticated route
touch src/app/ ( authenticated ) /posts/page.tsx
Create Component
src/app/(authenticated)/posts/page.tsx
'use client'
import { useAuth } from '@/hooks/auth'
export default function PostsPage () {
const { user } = useAuth ({ middleware: 'auth' })
return (
< div >
< h1 > Posts </ h1 >
</ div >
)
}
Add Navigation Link
Update navigation component to include the new route.
Testing Structure
Backend Tests (Pest)
tests/Feature/Auth/AuthenticationTest.php
test ( 'users can authenticate using the login screen' , function () {
$user = User :: factory () -> create ();
$response = $this -> post ( '/login' , [
'email' => $user -> email ,
'password' => 'password' ,
]);
$this -> assertAuthenticated ();
$response -> assertNoContent ();
});
Frontend Testing
Use Jest and React Testing Library for frontend tests:
import { render , screen } from '@testing-library/react'
import LoginPage from '@/app/(guest)/login/page'
test ( 'renders login form' , () => {
render (< LoginPage />)
expect ( screen . getByText ( 'Login' )). toBeInTheDocument ()
})
Build & Deployment
Backend Build
cd Backend
composer install --no-dev --optimize-autoloader
php artisan config:cache
php artisan route:cache
php artisan view:cache
Frontend Build
cd Frontend
npm run build
npm start
Next Steps
Architecture Overview Learn about the full-stack architecture
Authentication Deep dive into authentication flow