Inertia JS consume laravel api
Stefan Bogdanescu
Founder & Senior Architect · 2026-06-29
Inertia.js Consume Laravel API: Bridging the Gap Between SSR and RESTful Data
The world of full-stack development often involves juggling different paradigms: Server-Side Rendering (SSR), Single Page Applications (SPA), and pure RESTful APIs. When using a powerful stack like Laravel with Inertia.js, developers often encounter friction when trying to serve data in two different formats—the Inertia response structure versus a standard JSON API response.
This post dives into the specific problem you are facing: how to decouple your Inertia setup from your Laravel API endpoints so that you can serve generic JSON responses to any client (Vue SPA, React Native mobile app) without triggering Inertia’s strict requirement for an Inertia::render() response.
The Conflict: Inertia's Expectation vs. API Reality
The error message you are seeing—"All Inertia requests must receive a valid Inertia response, however a plain JSON response was received"—is not an error in the sense that your code is broken, but rather a security and framework integrity check. Inertia is designed to handle requests where it expects a view component (or an Inertia object) back from the server, as it manages the routing and rendering context for those pages.
When you use return Inertia::render('...'), you are explicitly telling Inertia: "Render this specific Vue/React component." When your controller returns plain JSON (return response()->json([...])), Inertia doesn't know how to interpret that data in its rendering pipeline, leading to the conflict.
The Solution: Decoupling Routing and API Endpoints
The key to solving this lies in understanding the distinct roles of Inertia and a standard Laravel API. They should not be conflated.
1. Standardizing for API Consumption
For any endpoint intended purely for data retrieval—which is exactly what you need for your mobile apps or decoupled frontends—you should treat it as a pure RESTful API route, completely separate from Inertia routes.
Best Practice: Use standard Laravel Controllers and return JSON responses exclusively for these endpoints. This adheres to the principles outlined when building robust APIs on platforms like laravelcompany.com.
Example Controller Implementation (API Route):
// app/Http/Controllers/PostController.php
use Illuminate\Http\Request;
class PostController extends Controller
{
public function getPosts()
{
// Fetch data using Eloquent or other models
$posts = \App\Models\Post::all();
// Return a standard JSON response, completely bypassing Inertia logic.
return response()->json($posts);
}
}
By structuring your routes this way (e.g., /api/posts), you create endpoints that are agnostic to the rendering framework. Any client can consume these endpoints using fetch or Axios without needing Inertia installed or involved in the request lifecycle.
2. When to Use Inertia vs. API
You should reserve Inertia for routes where server-side rendering (SSR) is explicitly required, such as loading an entire page that requires session data or complex component initialization.
- Inertia Routes: Used when the response is a view component (
Inertia::render(...)). - API Routes: Used when the response is raw data (
response()->json(...)).
If your Vue application needs to load an Inertia page and fetch some related data, you can handle both in a single request using Inertia's capabilities:
- The server renders the main Inertia view (using
Inertia::render). - The controller simultaneously fetches necessary API data and embeds it into the payload passed to the component.
Alternative Consideration: Vue Router vs. Inertia Router
You mentioned using vue-router instead of the Inertia router. While vue-router manages client-side navigation beautifully, Inertia.js is not just a router; it's an entire architectural layer that bridges server and client state. Replacing Inertia entirely to use pure Vue Router would mean sacrificing the seamless, server-driven context switching and data hydration that Inertia provides out of the box with Laravel.
For your goal—a generic backend serving data to multiple clients—sticking to a decoupled API approach (Solution 1) is far more scalable than trying to force Inertia into an API role.
Conclusion
To achieve a truly generic backend capable of serving JSON responses to any frontend (Vue SPA, React Native), the solution is separation of concerns. Treat your Laravel application as two distinct services: one for SSR/SPA integration via Inertia, and another for pure data delivery via RESTful APIs. By ensuring all API endpoints return standard JSON payloads, you resolve the conflict with Inertia and create a flexible architecture that scales effectively, mirroring the robust patterns found in modern backend development on platforms like laravelcompany.com.