Blogs
Serverless functions in Nuxt: backend power without a backend
NuxtServerless functions are tiny pieces of code that run on demand in the cloud. You don’t provision servers or infrastructure, or write scaling rules. Cloud providers handle the underlying infrastructure, automatically scaling resources based on demand.
They’re perfect for lightweight APIs, form handlers, webhooks, simple auth endpoints, and glue code.
How Nuxt does it (Nitro + H3)Nuxt has built-in support for serverless functions via Nitro (its server engine). Nitro compiles your server code to many targets (Node, Vercel, Netlify, Cloudflare Workers, etc.) and runs on top of H3, a tiny, fast HTTP framework.
You write your server-side logic inside the
server/api/
folder. Each file becomes an API endpoint automatically.// server/api/hello.ts export default defineEventHandler(() => { return { message: 'Hello from serverless' } })
This function will respond toGET /api/hello
with a JSON object. That’s it. Visit` /api/hello` in your browser or useFetch() from your frontend, and you get:{ "message": "Hello from serverless" }
Calling Your APIs from the FrontendYou can use
useFetch()
,useAsyncData()
, or$fetch()
to call these functions in your Vue components or pages.<script setup> const { data } = await useFetch('/api/hello') </script> <template> <p>{{ data.message }}</p> </template>
DeploymentNuxt works with Vercel, Netlify, Cloudflare, etc. Just push your code and your functions will auto-deploy as serverless endpoints.
Vercel → Serverless Functions
Netlify → Netlify Functions
Cloudflare → Workers
You don’t need to configure anything manually — just push your code.
Quick Tips to Not Shoot Yourself in the FootDon’t trust inputs, always validate.
Use environment variables for anything secret.
Keep functions small and focused.
Handle errors properly.
Don’t block the event loop with long-running tasks (offload to queues if needed).
Common Use CasesForm submissions
Email sending
API proxies
Auth endpoints
Data fetching or caching
Webhooks
With Nuxt and Nitro, serverless functions are just regular files that do backend magic. No setup, no stress. Whether you need a contact form endpoint, a webhook handler, or a simple API proxy, you can build it in minutes.No server management required.
Data Fetching Game in Nuxt: Advanced Level
NuxtNuxt's
useFetch
anduseAsyncData
composables are already powerful, but they got some seriously handy options that can level up how you handle data in your app.Here are a few advanced options that make a real difference in performance, UX, and network efficiency:
1.dedupe
: Avoid Duplicate RequestsNuxt by default cancels any request with the same key before starting a new one. This means if you have multiple components that fetch the same data, you’ll see unnecessary requests and a lot of canceled ones. With the option
dedupe: 'defer’
if an identical request is already pending, Nuxt won’t refetch and waits for the current one to finish.const { data } = await useFetch('/api/products', { dedupe: 'defer' // default value: cancel });
2.retry
andretryDelay
: Resilience for Unstable EndpointsNot all users have stable connection or fast Wi-Fi. For flaky APIs, edge functions, or when you want to add basic fault tolerance without custom logic, you can use Nuxt’s
retry
mechanism.const { data } = await useAsyncData('user', () => $fetch('/api/user'), { retry: 3, // number of retries after first request fails retryDelay: 1000 // milliseconds delay between retries });
3.delay
: Stagger Fetches for Smoother UXThis option adds a delay before making the request. You can use it to debounce fetches triggered by user input (though better handled via watch + debounce). It’s’ useful when you want to avoid flashing loading states for super quick page transitions.
const { data } = await useFetch('/api/settings', { delay: 300. // milliseconds before starting fetch });
Pro tip:
Always provide a key if you're using immediate: false, lazy, or working with reactive URLs to ensure deduplication and caching behave predictably.
These options let you finely tune your app's data layer for performance, UX, and network behavior. Mastering them in useFetch and useAsyncData helps you write cleaner, more efficient, and more resilient Nuxt apps.
Nuxt Essentials: A Practical Cheatsheet for Beginners & Returners
NuxtNuxt’s been around for a while -built on top of Vue- and with Nuxt 4 just around the corner, it’s a good time to revisit some of the basics. If you're new to Nuxt (or Vue), or just catching up after a break, here’s what people are actually talking about when they say things like 'Vite', 'Pinia', or 'Nitro'.
Folder structure in NuxtFolder
Purpose
pages/
Auto-routes based on file names
components/
Vue components
layouts/
Custom layouts
middleware/
Functions run before rendering page
plugins/
Inject functions/libraries
composables/
Auto-imported composables
Key tools in Nuxt ecosystemTool
Purpose
Nitro
Server engine (used for SSR, server APIs, middleware)
Vite
Frontend bundler (use for Dev server, build optimization)
Pinia
State management system
Now let's get into detail (only a bit)
Plugins:Plugins in Nuxt are a way to extend your app’s functionality by injecting features, libraries, or custom logic into the app context. They run before your Vue components are created. They run globally and are available everywhere without having to import it manually each time.
In Nuxt 3, you can create a plugin like:// /plugins/myPlugin.ts export default defineNuxtPlugin(nuxtApp => { nuxtApp.provide('hello', () => 'Hello from plugin!') })
And use it like:const hello = inject('hello')
Composables:In short: Composables = Reusable logic using Composition API
Let's look at a simple composable example:// composables/useCounter.ts export const useCounter = () => { const count = ref(0) const increment = () => count.value++ return { count, increment } }
You can use it in your vue component like:<script setup> const { count, increment } = useCounter() </script> <template> <button @click="increment">Clicked {{ count }} times</button> </template>
Middleware:// middleware/auth.global.ts export default defineNuxtRouteMiddleware((to, from) => { const user = useUser() if (!user.value) return navigateTo('/login') })
What is Nitro?Nitro is a lightweight universal server engine built by the Nuxt team. It’s what powers SSR (Server-Side Rendering), API routes, and deployment adapters in Nuxt 3.
Nitro: Next Generation Server Toolkit
What is Vite?Vite is a (blazing fast) modern frontend bundler with tree shaking, instant dev start and fast Hot Module Replacement.
Vite: the build tool for web
What's Pinia then?Pinia is the official state management library for Vue 3, and by extension, Nuxt 3.
Think of Pinia as Vuex’s leaner, friendlier successor. You define a store using "defineStore()" and use it in components without boilerplate.
It's lightweight and modular and there's first-class support for it in Nuxt (meaning it's officially integrated, fully supported, and works seamlessly out of the box)
The store for Vue.js
I've heard of Rollup and Rolldown, what are they?Rollup is a JavaScript module bundler (like Webpack or Vite's underlying engine for builds), known for being simple, fast, and tree-shake-friendly. It takes all your import/export JavaScript (or TypeScript) files, bundles them into one or more optimized output files.
In our context, Vite uses Rollup under the hood for production builds.
Rolldown is a newer project, currently under development (time of writing this article: June/July 2025).It's a Rollup-compatible bundler written in Rust, aiming to be blazing fast (like esbuild or Turbopack).
Powering Netherland’s largest real estate platform
VueAs published on "the official State of Vue.js report of 2025" earlier this year, I did a case study to showcase how Funda (real estate platform in the NL) makes use of Vue and Nuxt.
Little intro about Funda?
Funda is the Netherlands' leading real estate listing platform, serving millions of users daily. With hundreds of thousands of property listings and approximately 5 million daily searches, the platform demands exceptional performance, scalability, and search capabilities. Given the possible combination of search parameters and filters to cater to the users’ needs, this isn’t a trivial task. In addition, search engine optimization (SEO) is critical for ensuring visibility in property searches and maintaining a competitive edge for brokers.
How did we use Vue and Nuxt? And why?
Our web application combines modern technologies throughout its stack. For the frontend, we rely on Nuxt 3 with TypeScript and use Tailwind CSS as our CSS framework of choice, which also helps us write consistent styles according to our design system. The backend relies on the .NET framework, incorporating Elasticsearch to handle search functionality. The entire solution is hosted on the Microsoft Azure cloud platform.Beyond that, essential performance defaults, such as automatic code-splitting by route or predefined cache headers for assets, helped us get a good baseline. The built-in filesystem-based routing structure is also a big plus, as it makes navigation between listings and pages much simpler than solely using Vue Router (which is possible in Nuxt, too, if needed).
One key feature that makes domain-driven design possible is Nuxt's layer system. This allows us to split our codebase into multiple layers representing a domain. Each layer can have its own BFF and export its components. This makes it easy to separate concerns and keep the codebase clean and maintainable. Further, the layer system makes it easy to auto-import composables, components, and utilities, which is a big plus. Eventually, we benefit from further enhancements the Nuxt team ships consistently, from performance to developer experience improvements.
Nuxt 4 is coming out, what does it mean?
NuxtNuxt 3 was released in November 2022, about four years after Nuxt 2 originally launched. That’s four long years of development, beta cycles, and a full rewrite using Vue 3, Vite, and Nitro. The result? A versatile framework with a modern stack and delightful developer experience that got the frontend community excited.
Then in 2024, we started hearing rumors that Nuxt 4 was coming in June (but which June? Aha!).Flash forward to June 2025, and Nuxt 4 (alpha) is officially here — with a stable release promised by the end of the month. Cue the holy music.
What to expect from Nuxt 4?
You can read all about the new project structure and enhanced data fetching in official Nuxt articles (link) but what I want to highlight is how stress-free the migration from Nuxt 3 to Nuxt 4 is going to be.
We all remember the dark days of rewriting our Nuxt 2 projects to work with Nuxt 3. That was painful. But this time? Not the case.
As Daniel Roe has mentioned on multiple occasions, Nuxt 4 is not about “hype”, it’s about consistency and developer experience.
Nuxt 3 already felt solid and stable over the past couple years (and usage has been growing) Nuxt 4 just takes that solid foundation and makes it even more polished and thoughtfully engineered.
But Nuxt 4 is not a Pandora’s box for many of us. The new features were already available via compatibility mode, which makes the adaptation more straightforward, smooth and predictable.
But - Nuxt 5 is coming soon!
Yup, Nuxt 5 is already in the conversation. It’s possible we’ll have another major upgrade in 6 month or so, pending Nitro v3. And the question becomes whether to migrate a Nuxt 3 package to Nuxt 4 now or wait for Nuxt 5?
I think it’s definitely worth migrating to Nuxt 4 now. There is no major architectural overhaul and most modules require minimal changes to be compatible.Moreover, Core Nuxt modules are already using Nuxt 4 conventions and the community reception has been very positive so far.
PS. I really enjoyed watching this video from Alexander Lichter: TWO Major Nuxt versions coming? All you need to know about Nuxt 4 and Nuxt 5