nuxt

Stars and mentions

Last 30 days, Oct 5 – Nov 3

GitHub stars141
mentions34
05101520Oct 5Oct 19Nov 3
UTC days · repositories nuxt owns9 repositories

Package downloads

Cumulative recorded downloads · since 2025-10-19

npm554.9M
0138.7M277.5M416.2M554.9MOct 5Oct 19Nov 3
Oct 30npm: 1/13 packages observed

Across 13 known packages in repositories nuxt owns. Cumulative totals include recorded downloads before the selected range. Missing observations leave gaps; totals may be incomplete.

Top repositories

nuxt’s repositories ranked by new stars, as on trending.

Loading

Contributes to

Repositories outside nuxt’s account where nuxt opened or reviewed pull requests in the past 365 days.

Who noticed nuxt

Everyone who starred or forked nuxt’s repositories since the archive began in 2011.

Notable accounts

Ordered by the stars their own repositories have received.

Biggest fans

Accounts that starred the most of these repositories.

Breakout weeks

Each repository’s best week of new stars, with the release published around it.

Mentions

33posts
Nov 40 posts
  1. Framework Tracker compares two benchmarks: 1,000 router link components versus plain a tags, showing the components’ server-rendering cost. @danielroe.dev's PR benchmark showed rendering 200 internal NuxtLinks on the server dropping from 1.36ms to 0.57ms. PR: nuxt#36015

    5 likes
  2. Bluesky · · @nuxt.com · nuxt/image

    🚨 `@nuxt/image` security update 🚨 a single unauthenticated request to the default `/_ipx` route can crash your server, and may allow remote code execution, via a crafted multi-page image. 👉 this is fixed in 2.2.1 and 1.11.2, by bumping `ipx` github.com/nuxt/image/releases/tag/v2.2.1

    19 likes · 5 reposts
  3. 🚨 `@nuxt/image` security update 🚨 a single unauthenticated request to the default `/_ipx` route can crash your server, and may allow remote code execution, via a crafted multi-page image. 👉 this is fixed in 2.2.1 and 1.11.2, by bumping `ipx` github.com/nuxt/image/releases/tag/v2.2.1

    68 likes · 3 reposts · 4,791 views
  4. I asked Opus to teach me my own Nuxt PR. It came back with a 3 minute video: voiceover, animations synced to every word, and a quiz at the end. nuxt#36786 t.co

    8 likes · 238 views
  5. It's happening! 🔥 Nuxt is moving to Nitro 3. Can't wait to see what's coming next! nuxt#36671

    31 likes · 3 reposts · 690 views
  6. the latest nuxt nightly version with nitro rc is out now if you want to play around! 🔥

    43 likes · 5 reposts
  7. Nuxt SSR Streaming: Faster TTFB and the Response You Can't Change Later Classic server rendering in Nuxt is all or nothing. The server runs every plugin, resolves every awaited useFetch, renders the whole Vue tree to a string, and only then sends a single byte back. If one API call on the page takes 600ms, the browser sits staring at a blank tab for 600ms, unable to even start downloading your CSS. Streaming SSR has been one of the longest-standing open issues in the Nuxt repo, and as of Nuxt 4.5 it finally ships behind a flag. The win is real, but it comes with a contract change that is easy to trip over. Once the first byte is on the wire, the HTTP status and headers are locked in. Let's look at both halves. Turning it on Streaming is experimental and off by default. Enable it in nuxt.config.ts: export default defineNuxtConfig({ experimental: { ssrStreaming: true, }, }); With this on, Nuxt immediately flushes an HTML shell (your <head>, styles, preload hints, and entry scripts) and then streams the body as Vue renders it. The browser can start fetching CSS, fonts, and the JS entry chunk while your server is still waiting on that slow API. Bots and crawlers are excluded by default, so Googlebot and friends still get a fully buffered response. If you have an internal crawler or a link-preview service that chokes on streamed HTML, you can widen the match: export default defineNuxtConfig({ experimental: { ssrStreaming: { botRegex: /googlebot|bingbot|slackbot|my-internal-crawler/i, }, }, }); Be realistic about what improves. Time to First Byte drops reliably, because the shell no longer waits on your data. Largest Contentful Paint _may_ improve, depending on how much of the route's JavaScript overlaps the entry chunk and whether your LCP element sits behind the slow fetch. A page whose hero is rendered from an awaited API call still has to wait for that call before the hero arrives; you just stop wasting that time on idle network. The rule: the response is committed at byte one HTTP sends the status line and headers before the body. A buffered renderer can change its mind right up until the end. A streaming renderer cannot. Anything that tries to mutate the response _after_ rendering has begun simply can't reach the client. That covers more code than you might expect: <!-- pages/products/[slug].vue --> <script setup lang="ts"> const route = useRoute(); const { data: product } = await useFetch(`/api/products/${route.params.slug}`); if (!product.value) { // Too late under streaming: a 200 has already been sent setResponseStatus(useRequestEvent()!, 404); } // Also too late: the Set-Cookie header is already gone const lastViewed = useCookie("last-viewed"); lastViewed.value = String(route.params.slug); </script> The release notes call out setResponseStatus() in <script setup> and cookie writes during middleware as typical cases. Nuxt does not fail silently here: in development it logs a warning naming each dropped mutation. Treat those warnings as bugs, not noise. Nuxt also handles the common cases for you. Routes with redirect, cache, isr, swr, noScripts, or ssr: false route rules automatically fall back to the buffered renderer, so caching and redirect setups keep working. Living with it: opt out where the response matters The pragmatic approach is to stream the routes where the response is boring (marketing pages, docs, blog posts, dashboards behind auth) and keep buffering the ones that need to set status codes or cookies based on rendered data. Per-route opt-out uses routeRules: export default defineNuxtConfig({ experimental: { ssrStreaming: true, }, routeRules: { "/products/**": { streaming: false }, "/checkout/**": { streaming: false }, }, }); For logic that doesn't depend on rendered output, move it earlier instead of opting out. Nitro server middleware runs before the renderer starts, so headers and cookies set there are still in time: // server/middleware/visitor-id.ts export default defineEventHandler((event) => { if (!getCookie(event, "visitor-id")) { setCookie(event, "visitor-id", crypto.randomUUID(), { httpOnly: true, sameSite: "lax", maxAge: 60 * 60 * 24 * 365, }); } }); A quick checklist before you flip the flag on a real app: 1. Search for setResponseStatus, setHeader, setResponseHeader, and cookie writes in pages/, layouts/, components/, and route middleware. 2. Run the app in dev with streaming on and click through your key routes, watching for dropped-mutation warnings. 3. Decide per route: move the logic into server middleware, or add streaming: false. 4. Check that 404 pages still return 404 (curl with -I is enough), because a soft 404 is an SEO problem you won't see in the browser. Where this leaves you SSR streaming is the kind of feature that rewards a careful rollout: turn it on, read the dev warnings, opt out the handful of routes that need control of their response, and measure TTFB and LCP before and after rather than assuming. Because it is still experimental, expect the details to shift as the Nuxt team works toward v5. The Nuxt 4.5 release post and the original pull request are the best places to track the fallback rules and caveats as they evolve.

    1 reaction · 1 comment
  8. Nuxt 4.6 nuxt/server: Why Mixing h3 Imports Throws NUXT_E8012 A server/api/profile.get.ts handler that worked fine on Monday starts returning a NUXT_E8012 error on Tuesday, and the only thing that changed is a teammate added one line — reading the signed-in user's session with a helper imported from nuxt/server. Nothing else moved — not the route, not the defineEventHandler at the top of the file, not the dependency versions in any way you'd notice without reading package.json closely. The error message is honest about what's wrong, but only if you already know server/ now has two event shapes floating around, and that this one new line just handed a helper the wrong one. This article is written against Nuxt 4.6, verified at v4.6.2 (the current latest on npm as of this writing; nuxt/server itself shipped in 4.6.0, released October 5, 2026, per the official GitHub release notes). If you've read the server routes episode in this series, you already know how server/api and server/middleware route a request through Nitro — this one picks up what changed on top of that in 4.6: a second, explicit way to write the exact same kind of file, and the sharp edge where the two meet. What you'll learn By the end of this article you'll be able to: - Explain what nuxt/server is, why Nuxt 4.6 added it, and what it means for Nuxt to be "server-agnostic" - Tell apart the two coexisting ways to write server code in Nuxt 4.6 — the default h3 auto-imports and the new explicit nuxt/server imports - Read a NUXT_E8012 error and fix the file it's pointing at - Spot the subtler bug: helpers with the same name that behave differently depending on which source they came from - Decide whether to migrate existing server/ code now, or leave it exactly as it is Who this is for You've written server/api routes before — defineEventHandler, getQuery, readBody are already familiar. You don't need to have touched Nitro internals or h3 directly; this article treats the new nuxt/server import source as its own subject, not an h3 tutorial. Table of contents - [The problem: one new import, one confusing error](#the-problem-one-new-import-one-confusing-error) - [The mental model: two server APIs, one directory](#the-mental-model-two-server-apis-one-directory) - [Walking through it, stage by stage](#walking-through-it-stage-by-stage) - [Edge cases and gotchas](#edge-cases-and-gotchas) - [Best practices](#best-practices) - [FAQ](#faq) - [Cheat sheet](#cheat-sheet) - [Key takeaways](#key-takeaways) The problem: one new import, one confusing error Here's a server/api handler that looks like completely ordinary Nuxt 4 code, with one line added: // server/api/profile.get.ts import { useSession } from 'nuxt/server' export default defineEventHandler((event) => { const id = getRouterParam(event, 'id') const session = useSession(event, { password: process.env.NUXT_SESSION_PASSWORD! }) return { id, userId: session.data.userId } }) defineEventHandler and getRouterParam in this file are untouched — still the default auto-imports, exactly as they were last week. The only new thing is one call to useSession, imported explicitly from nuxt/server, to read the signed-in user's id out of the session. Run the dev server and hit the route, and the response comes back a 500: [nuxt] NUXT_E8012: `useSession` from `nuxt/server` was called with an h3 event. The handler was defined with h3's `defineEventHandler` (auto-imported), which passes a different event. Import `defineEventHandler` from `nuxt/server` alongside the helpers. The instinct is to assume a typo, a bad auto-import, or a stale .nuxt cache — none of which is true. getRouterParam and the rest of the file's identifiers were never touched, and this isn't a build failure either — the file compiles and the dev server starts just fine. The error only shows up once the route is actually hit, because it's thrown from inside useSession itself, the moment it notices the event it was handed doesn't look like the one nuxt/server expects. That's the whole bug: a handler still built with h3's own defineEventHandler handed one of nuxt/server's session helpers an event it can't work with — and it's also, it turns out, a deliberate guardrail rather than a bug at all. The mental model: two server APIs, one directory Before 4.6, server/ had exactly one API: a set of h3 and Nitro helpers (defineEventHandler, getQuery, readBody, getRouterParam, createError, and so on) that Nuxt auto-imports into every file under server/. That hasn't gone away — the release notes are explicit that the auto-imported helpers "are still h3's own helpers," unchanged, and nothing in the 4.6 release requires you to touch them. What 4.6 adds is nuxt/server — a second, explicit import source, described as "a complement to nuxt/app." Most of what it exports — getQuery, readBody, getRouterParam, and friends — are the exact same underlying h3/Nitro functions, re-exported under a new door, so importing them explicitly from nuxt/server instead of relying on the auto-import changes nothing about how they behave. A few exports are genuinely different, though: nuxt/server ships its own defineEventHandler (the one that builds the portable RequestEvent, with web-standard shape like event.req and event.res.headers), its own createError and sendRedirect with different contracts (more on those below), and its own session API — useSession, getSession, updateSession, clearSession — built specifically to read and write session data off that portable event. That session API is the clearest place NUXT_E8012 shows up. Each of those four helpers checks the event it's handed: if it looks like an h3 v1 event (no .req, just the legacy node request/response pair) rather than nuxt/server's own event, it throws NUXT_E8012, naming the helper and telling you to import defineEventHandler from nuxt/server too. That only happens if the handler around it is still built with the auto-imported defineEventHandler — the one that still produces an h3 v1 event. Reach for useSession (or one of its three siblings) inside a handler like that, and the event shape it's handed doesn't match what the helper needs. The session helpers aren't the only ones that check — the release notes describe the error more broadly, as something you'll hit from mixing the two import sources in general, so treat the session API as the headline example, not an exhaustive list. The reason nuxt/server exists at all is the headline of the release: Nuxt is moving toward being server-agnostic — not tied to Nitro as the only possible engine underneath server/. A handler built end-to-end on nuxt/server's portable event is meant to run unchanged whether the engine underneath it is Nitro, or the new experimental @nuxt/vite-server, or — per the release notes — Nitro v3 and h3 v2 once Nuxt 5 ships. Nitro itself isn't going anywhere; the same notes call it "still the right choice for almost everyone," including for 4.6. Key concept: in this episode's example, NUXT_E8012 comes from nuxt/server's session helpers refusing to work with an event they can't read, because the handler around them never opted into the portable event that makes them work — getQuery, readBody, and getRouterParam don't care which defineEventHandler built the event, so pairing those with the auto-import doesn't trip it. The release notes frame the error more generally, as something mixing the two import sources can produce, so don't assume every other helper is exempt just because these three are. Walking through it, stage by stage Stage 1 — the default path needs nothing from you If you've never heard of nuxt/server, your existing server/api, server/routes, and server/middleware files are unaffected by 4.6. The auto-imported defineEventHandler, getQuery, readBody, getRouterParam, and createError are exactly the h3 helpers they always were. Upgrading to 4.6 changes nothing here — this is the whole point of the release notes' line that "nothing in this release requires a migration." Stage 2 — opting in, one file at a time To build a handler around the portable event — and unlock nuxt/server's own defineEventHandler, createError, sendRedirect, and session helpers — you import explicitly, by name, from nuxt/server: // server/api/health.get.ts — fully opted in import { defineEventHandler, getQuery, useSession } from 'nuxt/server' export default defineEventHandler(async (event) => { const { verbose } = getQuery(event) const session = await useSession(event, { password: process.env.NUXT_SESSION_PASSWORD! }) return { ok: true, verbose: verbose === 'true', userId: session.data.userId } }) Because defineEventHandler here is nuxt/server's own version, the event it builds has .req on it — exactly the shape useSession checks for. getQuery behaves identically either way (it's the same h3 helper regardless of source), but the handler itself is opted all the way in, which is what the session API actually needs. Stage 3 — what actually trips NUXT_E8012 This is the pairing from the mental model above, put to use: switch the handler's defineEventHandler to the nuxt/server import too, and the session helper gets the portable event it's checking for. // fixed — defineEventHandler now comes from nuxt/server as well import { defineEventHandler, getRouterParam, useSession } from 'nuxt/server' export default defineEventHandler(async (event) => { const id = getRouterParam(event, 'id') const session = await useSession(event, { password: process.env.NUXT_SESSION_PASSWORD! }) return { id, userId: session.data.userId } }) Notice what doesn't need to change to clear the error: getRouterParam was never what threw NUXT_E8012, whether it came from the auto-import or from nuxt/server — it doesn't check which defineEventHandler built the event the way the session helpers do. The one identifier that has to move to fix this error is defineEventHandler itself, because that's what decides which event shape every helper in the handler gets handed. getRouterParam itself behaves the same from either source, for what it's worth — see the next section for the helpers that actually do differ. Stage 4 — the quieter trap: same name, different contract A couple of helpers behave differently depending on which source they came from, and none of these trip NUXT_E8012 either — that error is specific to the session API, not to these. nuxt/server's sendRedirect still sets the response status and Location header as a side effect, exactly like the auto-imported one — but instead of ending the response there, it also returns an HTML <meta http-equiv="refresh"> body as a fallback for a client that ignores the status code (inspecting the installed nuxt@4.6.2 package directly: dist/server/index.js's sendRedirect calls setResponseStatus(event, status) and event.res.headers.set('location', location) before returning that HTML string). So the redirect itself — the part every browser and fetch call actually relies on — works whether or not the handler returns that value; skipping the return only drops the fallback body, which matters solely to a user agent that ignores both the status and the header. Its createError takes status and statusText, where the h3-helper createError you already know takes statusCode and statusMessage — though nuxt/server's createError still accepts statusCode/statusMessage too, as deprecated aliases, so that direction keeps working. And response headers go through event.res.headers, a web-standard Headers-shaped object, rather than h3 v1's own header-setting helpers. // h3-style (auto-imported) — sends the full response immediately as a side effect export default defineEventHandler((event) => { return sendRedirect(event, '/login') }) // nuxt/server-style — sets status + Location immediately too, then returns a fallback body import { defineEventHandler, sendRedirect } from 'nuxt/server' export default defineEventHandler((event) => { sendRedirect(event, '/login') // no `return` here — the 302 and Location header are already set, so the // redirect still happens; only the <meta refresh> fallback page is skipped }) Neither example throws NUXT_E8012 — that error only ever comes from the session helpers, never from sendRedirect. The real gotcha here is narrower than it looks: dropping the return doesn't break the redirect, it just means a browser gets an empty body alongside the 302 instead of the fallback HTML. Worth knowing, but not worth losing an afternoon over — the loud NUXT_E8012 error from the session helpers is still the one that actually blocks a request. Stage 5 — deciding whether to opt in at all Nothing forces you to touch nuxt/server today. The case for doing it anyway, per the release notes, is forward-looking: Nuxt 5 will move to Nitro v3 and h3 v2, and server code written against nuxt/server on 4.6 "runs unchanged there." Code left on the auto-imported h3 helpers isn't broken by this — it keeps working exactly as it did on Nuxt 4.5 — but it's the code that will need attention whenever that migration comes. If you're starting a new server/ file today and have no reason to care about portability, the auto-imports remain the simpler, fully-supported default. If you're building something you expect to still be maintaining past the next major, nuxt/server is the version of "write it once" that this release is actually offering. Edge cases and gotchas It's not a per-project switch — it's per call. You can have some server/ files on the auto-imports and others fully on nuxt/server in the same project; most helpers don't care which source built the event they're handed. Only a session-helper call cares, and only at the moment it runs — importing useSession and never calling it is harmless, since the check happens inside the helper itself, not from a static scan of the file's imports. @nuxt/vite-server is explicitly experimental. The release notes introduce it alongside nuxt/server as a second, pure-Vite server builder, but they're equally explicit that "Nitro is still the right choice for almost everyone" right now. Treat it as a preview of where server-agnostic Nuxt is headed, not a production alternative to reach for in 4.6. Server-side useState/useRoute still don't belong in either server API. Nothing about nuxt/server changes the boundary the server routes episode in this series covers — both the h3-auto-import world and the nuxt/server world are still the Nitro/h3 side of the project, with no Vue application instance for a composable to attach to. Best practices - If a handler calls useSession, getSession, updateSession, or clearSession, make sure that same handler's defineEventHandler is imported from nuxt/server too. That pairing is the one thing NUXT_E8012 actually enforces — get it right and the rest of the file's imports (auto-imported or explicit) don't matter to this particular error. - Don't migrate existing files just because 4.6 shipped. The release notes are explicit that nothing requires it; migrate a file when you have an actual reason (adopting the session API, building for a new server builder, preparing early for Nuxt 5), not as busywork. - When you do reach for nuxt/server's own helpers, re-check the contract — not just sendRedirect and createError, but anything that used to write directly to the response. The upgrade guide's comparison table is the source of truth, not assumption-by-familiar-name. - If a NUXT_E8012 shows up in a file you didn't expect, look for a call to useSession/getSession/updateSession/clearSession and check what built the event around it — it's almost always a defineEventHandler that's still the h3 auto-import. FAQ Do I have to migrate my existing server/ code to nuxt/server? No. The 4.6 release notes say directly that nothing in the release requires a migration — files using only the auto-imported h3 helpers keep working exactly as they did on 4.5. What exactly causes a NUXT_E8012 error? Calling one of nuxt/server's session helpers — useSession, getSession, updateSession, or clearSession — inside a handler whose defineEventHandler is still the default auto-import. The helper gets handed an h3 v1 event instead of the portable one it needs, and throws at request time, naming itself in the error. It's not a build-time check and it's not about any other helper pairing — getQuery, readBody, and getRouterParam behave identically no matter which source you import them from. Is nuxt/server replacing Nitro? No. Nitro remains the default engine underneath both import styles in 4.6, and the release notes call it "still the right choice for almost everyone." nuxt/server is a portable way to write handlers that happen to run on Nitro today and could run on a different server builder later — it isn't a replacement for Nitro itself. Do sendRedirect, createError, and getRouterParam behave the same regardless of where I import them from? Mostly, but not entirely. getRouterParam/getRouterParams behave identically either way — both default to the raw, undecoded route segment, and both accept { decode: true } to decode it. createError does differ: nuxt/server's version takes status/statusText (it still accepts statusCode/statusMessage too, as deprecated aliases), while the auto-imported h3 helper only recognizes statusCode/statusMessage. sendRedirect sets the status and Location header as a side effect either way, then additionally returns a <meta refresh> fallback body from the nuxt/server version — skip the return and the redirect still happens, you just lose that fallback body. None of this is NUXT_E8012, which comes only from the session API checking the event shape it's handed. Should I use @nuxt/vite-server instead of Nitro? Not yet, for anything you're shipping. The release notes introduce it as experimental, in the same breath as recommending Nitro for almost everyone. It's worth knowing it exists as a sign of where Nuxt's server layer is heading, not as a current production choice. Cheat sheet | Situation | What to do | | --- | --- | | New server/ file, no portability need | Leave it on the default auto-imports — no import needed | | Want a handler portable beyond Nitro | Import everything server-related in that file from nuxt/server | | Calling getQuery/readBody from either source | Behaves identically — they're the same h3 helper either way | | Calling getRouterParam/getRouterParams from either source | Behaves identically — both default to the raw, undecoded segment; pass { decode: true } on either to decode it | | Calling useSession/getSession/updateSession/clearSession | Only works if that handler's defineEventHandler is also from nuxt/server | | NUXT_E8012 in a file you didn't expect | Find the session-helper call and check whether its handler still uses the auto-imported defineEventHandler | | Redirecting with the auto-imported sendRedirect | Just call it — it ends the response immediately as a side effect | | Redirecting with nuxt/server's sendRedirect | Sets status + Location immediately too; return sendRedirect(event, path) additionally sends a fallback body for clients that ignore the status | | Throwing with the auto-imported createError | { statusCode, statusMessage } | | Throwing with nuxt/server's createError | { status, statusText } | | Deciding whether to migrate at all | Only if you have a real reason — nothing requires it on 4.6 | | Trying @nuxt/vite-server | Experimental — fine to explore, not yet for production | <!-- playground:start --> 🎮 Try it yourself ▶️ Open the interactive playground → _Runs right in your browser — poke at it and watch the concept react live._ <!-- playground:end --> Key takeaways - Nuxt 4.6 added nuxt/server, a new explicit import source for server code, alongside the default auto-imported h3 helpers that server/ has always had — most of what it exports is the same h3/Nitro functions under a new door, not a parallel implementation. - NUXT_E8012 is narrower than "don't mix imports": it fires specifically when nuxt/server's session helpers (useSession, getSession, updateSession, clearSession) are called inside a handler whose defineEventHandler is still the auto-import — the fix is pairing that one import with nuxt/server too. - createError shares a name across both sources but not a contract (status/statusText vs. statusCode/statusMessage), and sendRedirect sets its status and Location header the same way in both but only returns a fallback body from nuxt/server — skipping that return loses the fallback body, not the redirect. getRouterParam/getRouterParams behave identically from either source. None of these throw NUXT_E8012. - Migrating existing code to nuxt/server is optional today, and mainly worth it if you want a handler to keep working unchanged once Nuxt 5 moves to Nitro v3 and h3 v2. <!-- quiz:start --> 🧠 Test yourself Think it clicked? Take the 8-question quiz → _Instant feedback, a hint on every question, and an explanation for each answer — right or wrong._ <!-- quiz:end --> The teammate's one-line import, explained That NUXT_E8012 from the top of the article wasn't a cache problem or a typo — it was nuxt/server's session API refusing to read a session off an event it doesn't recognize. Once you know the error belongs specifically to the session helpers, not to every helper in the file, it stops looking like a mystery and starts looking like a guardrail with a narrow, specific job — and the subtler case, the same-named helper that behaves differently with no error at all, is the one worth remembering long after a request stops failing. <!-- related:start --> 📚 Read next - Nuxt Server Routes Explained: How Nitro Builds Your API - Nuxt Hydration Mismatch: Why It Happens and How to Fix It - Nuxt 4.5 SSR Streaming: The Route Rules That Disable It <!-- related:end --> --- 🚀 Want more like this? Every guide, playground, and quiz lives on bestpractic.org — open it and sign up free so the next one finds you. Thanks for reading! Let's stay connected: - ⭐ GitHub — follow me and star the projects: github.com/parsajiravand - 💬 Discord — join the frontend best-practices community: discord.gg - 📸 Instagram — frontend best practices, daily: @bestpractice___

    7 reactions
  9. CVE-2026-114131: CVE-2026-114131: Nuxt Route Rules appMiddleware Bypass via Percent-Encoded Route Segments CVE-2026-114131: Nuxt Route Rules appMiddleware Bypass via Percent-Encoded Route Segments > Vulnerability ID: CVE-2026-114131 > CVSS Score: 6.5 > Published: 2026-10-22 Nuxt versions 3.11.0 through 3.21.3 and 4.0.0 through 4.4.3 contain an interpretation conflict between the route rules matching engine and the core page routing mechanism. By submitting percent-encoded request path segments, unauthenticated attackers can bypass route rules, including appMiddleware authorization guards, and access rendered server-side page payloads. TL;DR An interpretation conflict in Nuxt allows unauthenticated users to bypass route rules and appMiddleware by sending percent-encoded URLs, leading to unauthorized access to server-side rendered page content. --- ⚠️ Exploit Status: POC Technical Details - CWE ID: CWE-436 / CWE-863 - Attack Vector: Network (Unauthenticated) - CVSS v3.1 Score: 6.5 (Medium) - EPSS Score: 0.00289 (~20th percentile) - Impact: Middleware Bypass / SSR Data Confidentiality Loss - Exploit Status: Proof-of-Concept Available - CISA KEV Status: Not Listed Affected Systems - Nuxt 3.x deployments (versions >= 3.11.0 and < 3.21.4) - Nuxt 4.x deployments (versions >= 4.0.0 and < 4.4.4) - Web applications relying on routeRules appMiddleware for authentication guards - nuxt: >= 3.11.0, < 3.21.4 (Fixed in: 3.21.4) - nuxt: >= 4.0.0, < 4.4.4 (Fixed in: 4.4.4) Code Analysis Commit: 81f86ac fix(nuxt): decode percent-encoded paths for route rules matching Commit: 9123ed8 test(nuxt): add unicode and percent-encoded route rule unit tests Exploit Details - GitHub Security Advisory: Security advisory detailing percent-encoded route segment routeRules bypass. Mitigation Strategies - Upgrade the Nuxt package to a non-vulnerable version. - Normalize URI paths at reverse proxy or WAF boundaries prior to upstream server forwarding. - Enforce authorization checks inside server API routes and page inline guards. Remediation Steps: 1. Update package dependencies in package.json to nuxt version >= 3.21.4 or >= 4.4.4. 2. Run npm install or pnpm install to apply the updated dependency package. 3. Verify that route-rule matching succeeds for percent-encoded paths in test environments. References - GitHub Security Advisory GHSA-6gq8-jgmh-3ffp - NVD Vulnerability Details CVE-2026-114131 - Nuxt Patch Commit 81f86ac - Nuxt Test Commit 9123ed8 --- Read the full report for CVE-2026-114131 on our website for more details including interactive diagrams and full exploit analysis.

  10. CVE-2026-114130: CVE-2026-114130: Cross-Site Scripting via ASCII Control Characters in Nuxt Fallback Router CVE-2026-114130: Cross-Site Scripting via ASCII Control Characters in Nuxt Fallback Router > Vulnerability ID: CVE-2026-114130 > CVSS Score: 2.3 > Published: 2026-10-22 A Cross-Site Scripting (XSS) vulnerability exists in Nuxt when configured with pages disabled (pages: false). ASCII C0 control characters prefixing javascript: URIs bypass internal protocol classification in the fallback router, allowing unauthenticated attackers to execute arbitrary script in the victim's origin context upon user interaction. TL;DR Nuxt applications running with pages disabled fail to sanitize javascript: URIs prefixed with ASCII C0 control characters, resulting in reflected/DOM XSS when rendered within NuxtLink components. --- ⚠️ Exploit Status: POC Technical Details - CWE ID: CWE-79 - Attack Vector: Network - CVSS v4.0 Score: 2.3 (Low) - EPSS Score: 0.00329 (24.75th percentile) - Impact: Cross-Site Scripting (XSS) - Exploit Status: poc - CISA KEV Status: Not Listed Affected Systems - Nuxt 4.x applications configured with 'pages: false' - nuxt: >= 4.0.0, < 4.6.0 (Fixed in: 4.6.0) Code Analysis Commit: 355ed95 fix(nuxt): sanitize external href with URL probe base Commit: df46569 cherry-pick fix for sanitize external href into release branch Exploit Details - GitHub Security Advisory GHSA-jjm6-p2m9-9w4x: Proof of concept test cases within official advisory and repository patch commits Mitigation Strategies - Upgrade Nuxt framework to version 4.6.0 or higher. - Validate and sanitize user input before binding values to link properties in templates. - Implement strong Content Security Policy (CSP) headers prohibiting inline script execution. Remediation Steps: 1. Check current package dependencies using 'npm list nuxt' or 'pnpm list nuxt'. 2. Inspect 'nuxt.config.ts' for the presence of 'pages: false'. 3. Update the project dependency via 'npm install nuxt@^4.6.0' or 'pnpm update nuxt@^4.6.0'. 4. Rebuild and redeploy the application. References - GitHub Security Advisory GHSA-jjm6-p2m9-9w4x - Nuxt Pull Request #36459 - Fix Commit 355ed9565127ff9b1453deb7160059ed55b3cb85 - Fix Commit df46569d5d3c7a7799de54c328634168fbae70bb - Nuxt Release v4.6.0 - NVD Entry for CVE-2026-114130 --- Read the full report for CVE-2026-114130 on our website for more details including interactive diagrams and full exploit analysis.

Trending awards, every completed day and week
Gold
01st place finishes
Silver
12nd place finishes
Bronze
23rd place finishes
Awarded repositories
2Owned by nuxt now

Repositories

Ordered by gold, then silver, then bronze.

  1. frameworkBest: 2nd by stars, 206 stars011
  2. nuxtBest: 3rd by stars, 376 stars001

A repository earns an award for finishing first, second or third in a completed trending day or week, ranked by new stars, new forks or pull request authors. Awards follow a repository through renames and transfers and count toward its current owner. Weeks run Monday to Sunday, UTC.