Connecting Laravel 12 with Next.js: A Comprehensive Guide

Author

Kritim Yantra

Jun 05, 2025

Connecting Laravel 12 with Next.js: A Comprehensive Guide

In the ever-evolving web development landscape, combining Laravel (a powerful PHP backend framework) with Next.js (a modern React-based frontend framework) offers developers a robust, scalable, and high-performing full-stack solution. This comprehensive guide walks you through multiple approaches to integrating Laravel 12 with Next.js 15, covering setup, authentication, deployment, and optimization.


✨ Why Combine Laravel with Next.js?

Laravel brings:

  • Elegant syntax and MVC architecture
  • Powerful Eloquent ORM
  • Seamless authentication and routing

Next.js delivers:

  • Server-side rendering (SSR) and static site generation (SSG)
  • Superior React experience with file-based routing
  • Lightning-fast performance and image optimization

Together, they create:

  • A Laravel-powered backend handling logic and APIs
  • A Next.js frontend delivering SEO-friendly, interactive UIs

📁 Approach 1: Laravel as API Backend + Next.js Frontend

Laravel Setup:

  1. Install Laravel
composer create-project laravel/laravel laravel-backend
  1. Configure CORS in config/cors.php:
return [
    'paths' => ['api/*', 'sanctum/csrf-cookie'],
    'allowed_origins' => ['http://localhost:3000'],
    'allowed_methods' => ['*'],
    'allowed_headers' => ['*'],
    'supports_credentials' => true,
];
  1. Add API Routes in routes/api.php:
Route::middleware('auth:sanctum')->get('/user', fn (Request $request) => $request->user());
Route::get('/posts', [PostController::class, 'index']);
  1. Install Sanctum:
composer require laravel/sanctum
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
php artisan migrate

Next.js Setup:

  1. Create App:
npx create-next-app@latest nextjs-frontend
  1. Install Axios:
npm install axios
  1. API Service (lib/api.js):
const apiClient = axios.create({
  baseURL: 'http://localhost:8000/api',
  withCredentials: true,
});

export default {
  getPosts: () => apiClient.get('/posts'),
};
  1. Display Posts in pages/posts/index.js:
import { useEffect, useState } from 'react';
import api from '../../lib/api';

export default function Posts() {
  const [posts, setPosts] = useState([]);

  useEffect(() => {
    api.getPosts().then(res => setPosts(res.data));
  }, []);

  return (
    <ul>
      {posts.map(p => <li key={p.id}>{p.title}</li>)}
    </ul>
  );
}

🏠 Approach 2: Next.js API Routes Proxy

Use Next.js API routes as a proxy layer between the frontend and Laravel.

Example: pages/api/posts.js

import axios from 'axios';

export default async function handler(req, res) {
  try {
    const response = await axios({
      method: req.method,
      url: `http://localhost:8000/api/posts`,
      data: req.body,
    });
    res.status(response.status).json(response.data);
  } catch (error) {
    res.status(500).json({ error: 'Internal Server Error' });
  }
}

🛁 Approach 3: Integrated Deployment

Steps:

  1. Build Next.js:
npm run build && npm export
  1. Copy out/ folder content to Laravel public/

  2. Route Laravel wildcard to index:

Route::get('/{any}', fn() => file_get_contents(public_path('index.html')))->where('any', '.*');

🔐 Authentication with Laravel Sanctum

  1. Laravel .env:
SANCTUM_STATEFUL_DOMAINS=localhost:3000
SESSION_DOMAIN=localhost
  1. CSRF + Login in Next.js:
await axios.get('http://localhost:8000/sanctum/csrf-cookie', { withCredentials: true });
await axios.post('http://localhost:8000/login', credentials, { withCredentials: true });
  1. Auth Context:
export const AuthContext = createContext();

export function AuthProvider({ children }) {
  const [user, setUser] = useState(null);

  useEffect(() => {
    axios.get('/api/user', { withCredentials: true }).then(r => setUser(r.data));
  }, []);

  return <AuthContext.Provider value={{ user }}>{children}</AuthContext.Provider>;
}

🔄 State Management & SWR

  1. Install SWR:
npm install swr
  1. Create Hook:
import useSWR from 'swr';

export function usePosts() {
  const fetcher = (url) => fetch(url).then(res => res.json());
  const { data, error } = useSWR('/api/posts', fetcher);
  return { posts: data, isLoading: !error && !data, isError: error };
}
  1. Use in Component:
const { posts, isLoading } = usePosts();

🚀 Deployment Strategies

Separate Hosting:

  • Laravel: Laravel Forge / Shared Hosting / VPS
  • Next.js: Vercel / Netlify / Custom Node Server

Combined (Monolith):

  • Serve Next.js static build via Laravel public/

Docker:

Use docker-compose with services for Laravel, Next.js, and MySQL for unified local development and deployment.


Performance Optimization

Laravel:

  • php artisan route:cache
  • Redis for caching/sessions
  • Use Octane for long-running app

Next.js:

  • Static Generation (SSG)
  • Image optimization
  • Lazy loading + dynamic imports

Network:

  • Enable gzip/compression
  • Use CDN for assets
  • HTTP/2 for multiplexing

❓ Common Issues & Fixes

  • CORS Errors: Ensure correct CORS headers & withCredentials
  • CSRF Token: Always fetch /sanctum/csrf-cookie first
  • Session Cookie: Check domain, SameSite, and secure flags
  • API Slowness: Profile DB, use cache, or Octane

🎉 Conclusion

Laravel 12 and Next.js 15 together provide unmatched power and flexibility. With Laravel managing your backend APIs and Next.js delivering blazing-fast UIs, you can build everything from SPAs to large-scale web apps.

By following this guide, you're now equipped to:

  • Choose the right architecture (API-first or integrated)
  • Securely authenticate users across the stack
  • Optimize performance and prepare for deployment

Now it's your turn to innovate. Happy coding! 🧰

Tags

Comments

No comments yet. Be the first to comment!

Please log in to post a comment:

Sign in with Google

Related Posts