Nuxt renders a beautiful public site, then the logged-in list comes back empty on the server and fine in the browser. That is the cookie, not Nuxt. Here is the Nuxt side of a Laravel API: the URL, the request, and where server rendering stops.
TL;DR
- Start new front ends on Nuxt 4; Nuxt 3 stopped receiving updates on 31 July 2026.
- Keep the Laravel origin in
runtimeConfig.public.apiUrl, overridden byNUXT_PUBLIC_API_URL. credentials: 'include'sends the cookie from the browser, not from the Nuxt server.- Use the Sanctum session cookie, not a token in
localStorage.
Use Nuxt when the public site is the product and Laravel is the API behind it. Nuxt 3 stopped receiving updates on 31 July 2026, so a new front end starts on Nuxt 4. Nuxt 4.6 requires Node 22.22.3 or newer, Node 24.15.0 or newer, or Node 26. That is stricter than the Vite floor in the requirements. Do not start here for an internal tool. The Vue starter kit already has login and routing. That choice is Inertia, a SPA, or Nuxt.
The API URL#
Gotcha: hardcoded localhost ships
Keep the Laravel origin in runtime config. A hardcoded localhost:8000 inside a component is the URL that ships to production.
npm create nuxt@latestexport default defineNuxtConfig({
runtimeConfig: {
public: {
apiUrl: "http://localhost:8000",
},
},
});Set NUXT_PUBLIC_API_URL in the Nuxt environment when the host changes. Nuxt maps that name onto runtimeConfig.public.apiUrl.
The request#
Heads up: SSR has no Laravel cookie
credentials: 'include' sends the session cookie from the browser. It does not attach that cookie when Nuxt server-renders an absolute Laravel URL, because the Nuxt server never received a cookie that lives on the Laravel origin. A logged-in list has to load in the browser, or through a relative proxy that forwards the cookie.
The cookie only exists after the Sanctum flow: stateful domains, supports_credentials, GET /sanctum/csrf-cookie, then POST /login. Those steps are Sanctum for a Vue SPA. Nuxt’s dev server is usually port 3000, so that origin is the one you add. CORS for that port is the CORS guide. This page does not copy either setup.
<script setup lang="ts">
const config = useRuntimeConfig();
const { data, error } = await useFetch(`${config.public.apiUrl}/api/posts`, {
credentials: "include",
});
</script>
<template>
<p v-if="error">Could not load posts.</p>
<article v-for="post in data?.data" :key="post.id">
<h2>{{ post.title }}</h2>
</article>
</template>data.data is there because a Laravel paginator or an API resource collection returns { data, links, meta }. The resource class is API resources. If the controller returns a raw array, drop the extra .data. Guessing which shape you have is how the list renders blank.
Check the shape before you render
Log data.value once in the browser console. If it has data, links and meta, keep data?.data. If it is an array, drop the extra .data.
Auth from Nuxt#
Call /sanctum/csrf-cookie and /login on the Laravel origin, with credentials, before this useFetch expects a user. A 401 means there is no session. A 419 means the CSRF cookie was missing. Both are diagnosed in the Sanctum guide. Nuxt middleware can redirect to your login page on 401. It cannot fix the cookie.
Tip: cookie, not localStorage
Do not put a Laravel token in localStorage for this first-party site. Sanctum’s own docs tell a first-party SPA to use the session cookie.
Where this stops#
Admin screens that only staff use can stay on Inertia inside Laravel. You do not have to rebuild them in Nuxt. Deploy the two apps as two processes. The Laravel half still follows deploy, including public/hot and php artisan optimize.
Recap#
- Nuxt 4 for new front ends; check the Node floor.
- API origin in runtime config, not in components.
- Server rendering cannot send a cookie that lives on the Laravel origin.
- Sanctum, CORS and the resource shape each have their own guide.
FAQ#
Should I use Nuxt 3 or Nuxt 4 with Laravel?
Nuxt 4. Nuxt 3 stopped receiving updates on 31 July 2026.
Why is my Nuxt useFetch to Laravel unauthenticated during SSR?
The session cookie lives on the Laravel origin, so the Nuxt server never has it. Load logged-in data in the browser, or proxy through a relative path that forwards the cookie.
Why does my Nuxt list render blank?
A Laravel paginator or resource collection returns { data, links, meta }. Loop over data.data, or drop .data if the controller returns a plain array.



