# Što ćete naučiti#
Ovaj vodič objašnjava Next.js rate limiting za Route Handlers, Server Actions i Edge runtime te kako ga kombinirati sa zaštitom od botova. Dobit ćete kod koji možete kopirati i zalijepiti za token bucket ograničenja, Redis-backed konzistentnost kroz serverless instance i praktična WAF ili CDN pravila.
Napisano je za timove koji isporučuju Next.js aplikacije s javnim API-jima, auth tokovima, endpointovima za pretraživanje, kontakt formama ili bilo kojom rutom koja privlači scrapere i credential stuffing. Ako želite i širi sigurnosni baseline, krenite s našom kontrolnom listom sigurnosti web aplikacija.
# Zašto je ograničavanje stope posebno važno u Next.js-u#
Next.js olakšava izlaganje moćnih serverskih mogućnosti kroz Route Handlers i Server Actions. To istovremeno čini zloupotrebu jeftinijom za napadače, a skupljom za vas.
Tipični stvarni načini “pucanja” koje viđamo u auditima i post-mortem analizama incidenata:
- Credential stuffing na
/api/loginstvara CPU skokove, opterećenje baze i troškove trećih auth servisa. - Scraperi gađaju search i product endpointove s visokom konkurentnošću, uzrokuju cache missove i origin promet.
- Spam formi napuhuje račune email providera i puni vaš CRM smećem.
- LLM crawleri i generički botovi pokreću skupe server komponente i server-side rendering putanje.
Dobra strategija nije jedan limiter. To je slojeviti sustav koji rano blokira očitu zloupotrebu i primjenjuje stroža pravila samo tamo gdje je važno.
# Pregled arhitekture: slojeviti model obrane#
Koristite najjeftiniju kontrolu prvu, zatim postupno skuplje provjere.
| Sloj | Gdje se izvršava | Najbolje za | Tipični alati |
|---|---|---|---|
| CDN ili WAF pravila | Prije aplikacije | Poznati loši botovi, geo pravila, osnovna pravila rate-a | Cloudflare WAF, Vercel WAF, AWS WAF |
| Edge middleware ili Edge Route Handlers | Na edgeu | Brzo oblikovanje prometa na razini IP-a, rana odbijanja, provjere po headerima | Next.js Middleware, Edge runtime |
| App-level limiter (Redis-backed) | Node runtime ili Edge s Redis HTTP | Limiti za autentificirane korisnike, kvote po korisniku, token bucket burstovi | Upstash Redis, Redis na Fly, managed Redis |
| Throttle na razini poslovne logike | Unutar actiona i servisa | Kontrola troškova, zaštita downstreama | DB-level capovi, queueing, circuit breaker-i |
Odabir runtimea je bitan jer Edge može odbiti ranije, ali ima ograničenja. Ako odlučujete između Edge i Node obrazaca, pročitajte Next.js Edge runtime vs Node.js runtime.
🎯 Ključna poruka: Promatrajte rate limiting kao sustav. CDN/WAF blokira šum, Edge jeftino odbija, a Redis-backed app limiti dosljedno provode stvarne kvote.
# Odabir pravog algoritma ograničavanja#
Većina timova krene s fiksnim prozorima i brzo požali zbog ponašanja burstova. Token bucket i leaky bucket su obično bolji za korisničko iskustvo.
Fiksni prozor (Fixed Window)#
- Primjer: 100 zahtjeva u minuti.
- Problem: napadač može poslati 100 zahtjeva na kraju jedne minute i 100 na početku sljedeće, čime efektivno udvostruči propusnost.
Klizni prozor (Sliding Window)#
- Izravnava skokove, ali može biti složeniji i “teži” za pohranu.
- Dobar za precizno provođenje, posebno na WAF sloju.
Token Bucket (preporučeno za većinu Next.js aplikacija)#
- Zamislite kantu koja se puni stalnom brzinom.
- Dopušta kratke burstove uz kontrolu dugoročne stope.
- Dobro za UX: korisnici mogu refreshati ili retryati bez trenutne blokade.
Praktična početna točka za token bucket postavke:
| Tip endpointa | Održiva stopa | Burst | Napomene |
|---|---|---|---|
| Login, OTP, reset lozinke | 5 po minuti | 10 | Dodajte i ključeve po računu i po IP-u |
| Search | 30 po minuti | 60 | Agresivno cacheirajte i razmotrite bot pravila |
| Kontakt forma | 2 po minuti | 5 | CAPTCHA dodajte tek nakon sumnje |
| Javni API (bez auth) | 60 po minuti | 120 | Preferirajte API ključeve kad je moguće |
| Server Actions koje mijenjaju podatke | 20 po minuti | 40 | Ključ po user ID-u i sessionu |
# Strategija ključeva: izbjegnite limite samo po IP-u#
Limiti samo po IP-u su jednostavni, ali uzrokuju lažno pozitivne blokade za:
- Korporativne NAT-ove
- Mobilne operatere
- Dijeljeni Wi‑Fi
- Proxye i VPN-ove
Preferirajte kompozitne ključeve:
- 1Authenticated user ID kad je dostupan.
- 2API key za programatski pristup.
- 3Session ID za anonimne, ali cookie-based tokove.
- 4IP kao sekundarna dimenzija.
- 5Gruba UA kategorija (coarse UA bucket) kako biste smanjili trivijalno zaobilaženje.
Siguran obrazac je ograničavati i po korisniku i po IP-u, pa blokirati tek kada su oba “abusive”, ili primijeniti strožu akciju kad je jedna dimenzija ekstremna.
⚠️ Upozorenje: Nikad se ne oslanjajte na
x-forwarded-forosim ako ste iza pouzdanog proxya i vaša platforma to garantira. Na većini platformi trebate koristiti request IP koji daje runtime ili provjerene headere.
# Next.js rate limiting za Route Handlers (Node Runtime)#
Node runtime je najfleksibilniji za Redis klijente i crypto biblioteke. Također je čest za pristup bazi i težu logiku.
Korak 1: Definirajte Token Bucket u Redis-u#
Token bucket treba pohraniti dvije vrijednosti po ključu: trenutne tokene i timestamp zadnjeg refill-a. Implementirat ćemo ga jednim atomskim Redis skriptom kako bi konkurentni zahtjevi bili ispravno obrađeni.
Ovaj primjer je zamišljen za Redis-kompatibilne servise koji podržavaju Lua skripte. Ako vaš provider ne podržava skripte, koristite server-side rate limit proizvod ili drugi algoritam.
// lib/rateLimit.ts
export type RateLimitResult = {
allowed: boolean;
remaining: number;
retryAfterMs: number;
};
export type TokenBucketConfig = {
capacity: number; // max tokens
refillPerSec: number; // tokens per second
};
const LUA_TOKEN_BUCKET = `
local key = KEYS[1]
local capacity = tonumber(ARGV[1])
local refill_per_sec = tonumber(ARGV[2])
local now_ms = tonumber(ARGV[3])
local data = redis.call("HMGET", key, "tokens", "ts")
local tokens = tonumber(data[1])
local ts = tonumber(data[2])
if tokens == nil then tokens = capacity end
if ts == nil then ts = now_ms end
local delta_ms = math.max(0, now_ms - ts)
local refill = (delta_ms / 1000.0) * refill_per_sec
tokens = math.min(capacity, tokens + refill)
local allowed = 0
if tokens >= 1.0 then
allowed = 1
tokens = tokens - 1.0
end
redis.call("HMSET", key, "tokens", tokens, "ts", now_ms)
redis.call("PEXPIRE", key, math.ceil((capacity / refill_per_sec) * 1000) + 60000)
local retry_after_ms = 0
if allowed == 0 then
retry_after_ms = math.ceil((1.0 - tokens) / refill_per_sec * 1000)
end
return {allowed, math.floor(tokens), retry_after_ms}
`;Korak 2: Povežite ga s vašim Redis klijentom#
Ispod je minimalni wrapper koji pretpostavlja da vaš Redis klijent ima eval metodu.
// lib/rateLimitRedis.ts
import type { RateLimitResult, TokenBucketConfig } from "./rateLimit";
export async function tokenBucketLimit(opts: {
redis: any;
key: string;
config: TokenBucketConfig;
nowMs?: number;
}): Promise<RateLimitResult> {
const nowMs = opts.nowMs ?? Date.now();
const { capacity, refillPerSec } = opts.config;
const res = await opts.redis.eval(LUA_TOKEN_BUCKET, {
keys: [opts.key],
arguments: [String(capacity), String(refillPerSec), String(nowMs)],
});
const allowed = res[0] === 1;
const remaining = Number(res[1] ?? 0);
const retryAfterMs = Number(res[2] ?? 0);
return { allowed, remaining, retryAfterMs };
}Ako vaša Redis biblioteka koristi drugačiji eval potpis, prilagodite samo taj dio. Logika ostaje ista.
Korak 3: Primijenite u Next.js Route Handleru#
Primjer rute: app/api/search/route.ts
// app/api/search/route.ts
import { NextResponse } from "next/server";
import { tokenBucketLimit } from "@/lib/rateLimitRedis";
import { redis } from "@/lib/redis";
export const runtime = "nodejs";
function getClientIp(req: Request) {
return req.headers.get("x-forwarded-for")?.split(",")[0]?.trim() ?? "unknown";
}
export async function GET(req: Request) {
const ip = getClientIp(req);
const key = `rl:search:ip:${ip}`;
const limit = await tokenBucketLimit({
redis,
key,
config: { capacity: 60, refillPerSec: 0.5 }, // 30/min sustained, 60 burst
});
if (!limit.allowed) {
return new NextResponse("Too Many Requests", {
status: 429,
headers: {
"Retry-After": String(Math.ceil(limit.retryAfterMs / 1000)),
},
});
}
// Continue with search logic...
return NextResponse.json({ ok: true, remaining: limit.remaining });
}Ovo je “dovoljno dobro” za mnoge javne endpointove, ali za autentificirane korisnike htjet ćete bolje ključeve.
# Next.js rate limiting za Server Actions#
Server Actions su moćne jer se izvršavaju na serveru i mogu se pozivati iz formi i komponenti. Također su atraktivne za zloupotrebu jer često pokreću mutacije i skupe downstream pozive.
Obrazac: Omotajte Server Actions limiterom#
Možete izgraditi wrapper koji:
- Izvodi stabilan ključ iz user ID-a ili sessiona.
- Kod neautentificiranih pada natrag na IP.
- Vraća siguran error koji UI može obraditi.
// lib/withRateLimit.ts
"use server";
import { headers } from "next/headers";
import { tokenBucketLimit } from "@/lib/rateLimitRedis";
import { redis } from "@/lib/redis";
type LimiterOpts = {
name: string;
capacity: number;
refillPerSec: number;
keySuffix?: string;
};
function getIpFromHeaders() {
const h = headers();
return h.get("x-forwarded-for")?.split(",")[0]?.trim() ?? "unknown";
}
export function withRateLimit<TArgs extends any[], TResult>(
action: (...args: TArgs) => Promise<TResult>,
opts: LimiterOpts
) {
return async (...args: TArgs): Promise<TResult> => {
const ip = getIpFromHeaders();
const key = `rl:action:${opts.name}:ip:${ip}:${opts.keySuffix ?? "default"}`;
const limit = await tokenBucketLimit({
redis,
key,
config: { capacity: opts.capacity, refillPerSec: opts.refillPerSec },
});
if (!limit.allowed) {
throw new Error("RATE_LIMITED");
}
return action(...args);
};
}Zatim ga koristite:
// app/actions/submitContact.ts
"use server";
import { withRateLimit } from "@/lib/withRateLimit";
async function submitContactImpl(formData: FormData) {
// validate, store, notify
return { ok: true };
}
export const submitContact = withRateLimit(submitContactImpl, {
name: "submitContact",
capacity: 5,
refillPerSec: 0.03, // roughly 2/min sustained
});Edge vs Node za Server Actions#
U praksi, većina Server Actions radi u Node runtimeu na platformama poput Vercela, i to je obično ono što želite zbog Redis klijenata i auth SDK-ova. Ako forsirate Edge, provjerite da su sve ovisnosti Edge-kompatibilne i da Redis-u pristupate preko HTTP-a.
Ako želite dublju usporedbu runtimea, koristite naš vodič Edge vs Node.
# Edge runtime obrasci: brzo odbijanje, ograničeno stanje#
Edge runtime je odličan za rano i jeftino odbijanje te za oblikovanje prometa prije nego dođe do origina. Kompromis su ograničena kompatibilnost biblioteka i upravljanje stanjem.
Opcija A: Edge Middleware “Gate”#
Koristite middleware za blokiranje očite zloupotrebe za cijele grupe ruta, poput /api/ ili osjetljivih stranica.
- Odbijte poznate loše botove po User-Agent signaturi.
- Nametnite jednostavne per-IP limite koristeći edge KV ili vendor-specifični rate limit servis.
- Za interne pozive zahtijevajte minimalni header.
Budući da se Next.js Middleware izvršava na Edgeu, to je dobro mjesto za gruba pravila i redirect ili block.
ℹ️ Napomena: Middleware nije idealno mjesto za stroge kvote jer može dodati latenciju i morate izbjegavati high-cardinality pozive stanja na svaki zahtjev. Koristite ga za shaping i jeftine provjere.
Opcija B: Edge Route Handler s Redis HTTP#
Neki managed Redis provideri nude HTTP-based API koji je Edge-friendly. Ista token bucket logika vrijedi, ali se mijenjaju karakteristike klijenta i latencije.
Kad ste na edgeu, budite realni oko latencije. Ako je vaš Redis daleko od edge POP-a, možete dodati 30 do 100 ms po zahtjevu, što je preskupo za high-volume rute. U tim slučajevima neka WAF ili CDN riješi većinu šuma, a Redis provjere zadržite za autentificirane ili skupe operacije.
# Redis-backed limiti: konzistentnost kroz serverless instance#
U serverless i autoscaled okruženjima, in-memory limiti se često resetiraju i nisu dijeljeni između instanci. Redis to rješava kao zajedničko spremište.
Kada se isplati Redis-backed ograničavanje#
- Imate API ključeve i kvote.
- Trebate per-user throttle za Server Actions.
- Plaćate po requestu trećim stranama i želite kontrolirati trošak.
- Trebate dosljedno provođenje kroz regije ili instance.
Kada se ne isplati Redis-backed ograničavanje#
- Čisto statične stranice iza CDN-a.
- Endpointovi već zaštićeni WAF pravilima i cachingom.
- Interni alati s malim prometom.
Praktičan pristup je implementirati Redis-based limiting samo za ove kategorije:
| Kategorija | Primjeri endpointova | Preporučeni ključ | Zašto |
|---|---|---|---|
| Autentifikacija | /api/login, /api/otp | user ID plus IP | Sprječava stuffing i lockoutove računa |
| Skupa čitanja | /api/search, /api/reports | user ID ili session | Štiti DB i sprječava scraping |
| Mutacije | Server Actions koje pišu | user ID | Sprječava spam i zloupotrebu |
| Trošak trećih strana | AI pozivi, SMS, email | user ID plus plan | Sprječava “bill shock” |
# WAF i CDN pravila: zaštita s najvećim ROI-jem#
Rate limiting na aplikacijskom sloju je precizniji, ali je skuplji. WAF i CDN pravila trebaju zaustaviti većinu lošeg prometa prije nego dotakne vaš Next.js runtime.
Praktična WAF pravila koja rade#
- Request rate pravila za
/api/login,/api/otp,/api/reset-password. - Bot score ili managed bot protection za
/api/search,/products,/sitemap.xml. - Geo pravila ako je vaš business ograničen na regiju.
- Challenge na sumnjive obrasce umjesto tvrdog blocka.
Mnogi timovi vide da top 1 do 5 posto zlonamjernih IP-ova generira velik dio zahtjeva. Uobičajeno je značajno smanjiti origin promet blokiranjem ili izazivanjem (challenge) tih IP-ova na edgeu. Cloudflare je javno dijelio case studyje gdje bot management značajno smanjuje bot promet, a u praksi često vidimo dvoznamenkasta smanjenja origin zahtjeva nakon uključivanja bot pravila i tuniranja.
💡 Savjet: Za rute visokog rizika krenite s “challenge”, ne s “block”. To smanjuje lažno pozitivne blokade, a i dalje automatiziranu zloupotrebu čini skupom.
Primjer pristupa pravilima prema osjetljivosti rute#
| Ruta | Zadana akcija | Eskalacija | Napomene |
|---|---|---|---|
/api/login | strogi limit | challenge ili block | Dodajte per-account throttle u aplikaciji |
/api/search | umjeren limit | challenge | Cacheirajte rezultate i paginirajte |
/api/public/* | umjeren limit | block kod očite zloupotrebe | Potaknite API ključeve |
/app/* autentificirane stranice | lagani shaping | app-level user limiti | Fokus na zlonamjerne sessione |
# Dizajn odgovora: 429, Retry-After i UX#
Uvijek vraćajte:
429 Too Many RequestsRetry-Afterheader u sekundama- Stabilan error code koji klijent može interpretirati
Za Server Actions mapirajte error na UI poruku poput “Previše pokušaja, pokušajte ponovno za 30 sekundi” i držite to konzistentno kroz aplikaciju.
Ako nudite API-je trećim stranama, dokumentirajte limite i vraćajte headere poput:
X-RateLimit-LimitX-RateLimit-RemainingX-RateLimit-Reset
Čak i ako danas ne implementirate sve, krenite s Retry-After.
# Monitoring i alerting: otkrijte zloupotrebu i prilike za tuniranje#
Rate limiting bez monitoringa postaje tihi utjecaj na korisnike. Pratite i dopušten i blokiran promet.
Što mjeriti:
| Metrička | Zašto je bitno | Dobar trigger za alert |
|---|---|---|
| Ukupna stopa 429 | Otkriva pogrešne postavke | Nagli porast iznad baselinea |
| 429 po ruti | Nalazi “vruće” endpointove | Jedan endpoint “iskoči” |
| 429 po tipu ključa | Dijagnosticira false positive | Mnogo različitih IP-ova blokirano |
| Top blokirani ključevi | Identificira izvore zloupotrebe | Jedan ključ dominira |
| Latencija dodana limiterom | Osigurava da limiter nije usko grlo | P95 raste nakon rollouta |
| Redis greške i timeoutovi | Sprječava fail-open iznenađenja | Error rate iznad 1 posto |
Logirajte strukturirano. Uključite:
- rutu
- naziv limitera
- tip ključa, ne puni ključ ako sadrži osobne podatke
- preostale tokene
- retryAfter
Ako gradite observability baseline, slijedite naš vodič za observability web aplikacija i osigurajte da se logovi i metrike mogu korelirati s request ID-jevima.
⚠️ Upozorenje: Ne logirajte sirovi IP zajedno s korisničkim identifikatorima ako to ne trebate. Tretirajte ove logove kao osjetljive i primijenite retention politike.
# Ublažavanje lažno pozitivnih blokada i siguran rollout#
Lažno pozitivne blokade su glavni razlog zašto timovi isključuju limite. Dizajnirajte za postupan rollout i brzo ublažavanje.
Koristite ove poluge za ublažavanje#
- 1
Shadow mode
Izračunavajte limite i logirajte would-block događaje, ali ne blokirajte. Rolloutajte 24 do 72 sata i pregledajte. - 2
Tiered pragovi
Postavite više limite za autentificirane korisnike i korisnike koji plaćaju. - 3
Allowlists
Dopustite IP-ove ureda, uptime monitore, CI i pouzdane third-party servise. - 4
Dizajn ključeva
Koristite user ID kad je dostupan. Izbjegnite IP-only za autentificirane tokove. - 5
Grace za retry
Token bucket burst kapacitet sprječava slučajne blokade zbog dvostrukog slanja i nestabilnih mobilnih veza. - 6
Eskalacija umjesto blokiranja
Challenge, dodajte CAPTCHA ili zahtijevajte email verifikaciju prije hard blocka.
Uobičajeni false-positive scenariji i rješenja#
| Scenarij | Simptom | Rješenje |
|---|---|---|
| Korporativni NAT | Mnogo korisnika dijeli jedan IP | Ključ po user ID-u, povećajte IP burst |
| NAT mobilnog operatera | Nasumični block na mobitelu | Preferirajte session ključ, smanjite težinu IP-a |
| Agresivni prefetching | Dodatni GET promet | Izuzmite prefetch headere ili specifične rute |
| Webhookovi | Provider retrya kod greške | Veći burst, idempotency ključevi, allowlist IP-ova providera |
# Kako sve složiti: praktična baseline konfiguracija#
Ako želite konfiguraciju koja radi za većinu SaaS i content platformi, krenite ovdje i prilagođavajte.
| Komponenta | Baseline postavka | Primjenjuje se na |
|---|---|---|
| WAF pravilo | 20 zahtjeva u 10 sekundi po IP-u za /api/login | Zaustavlja burstove credential stuffinga |
| Edge shaping | Blokirajte očite loše botove po UA plus ponašanju | Jeftino rano odbijanje |
| Redis token bucket | Login: 5/min održivo, 10 burst po IP-u plus po računu | Konzistentno provođenje |
| Redis token bucket | Search: 30/min održivo, 60 burst po sessionu | Štiti DB |
| Action wrapper | Mutacije: 20/min održivo, 40 burst po korisniku | Sprječava spam |
| Observability | Alert na stopu 429 i Redis greške | Sprječava tihi utjecaj na korisnike |
Povežite ovo s vašim ukupnim sigurnosnim programom. Rate limiting i zaštita od botova su ključne kontrole uz validaciju inputa, hardening autentifikacije i secure headere, sve pokriveno u našoj kontrolnoj listi sigurnosti web aplikacija.
# Ključne poruke#
- Koristite slojevitu strategiju: prvo WAF ili CDN pravila, zatim Edge shaping, a Redis-backed token bucket limite za dosljedne kvote u Next.js-u.
- Izbjegavajte IP-only ključeve za autentificirane tokove; preferirajte kompozitne ključeve poput user ID plus IP kako biste smanjili false positive iza NAT-a.
- Implementirajte token bucket limite za bolji UX: dopustite kratke burstove uz održive stope i uvijek vraćajte
429sRetry-After. - Ograničite Server Actions tako da ih omotate reusable limiterom i spremate brojače u Redis kako bi limiti vrijedili kroz serverless instance.
- Pratite stopu 429, top blokirane ključeve, Redis latenciju i greške; rolloutajte u shadow modeu prije provođenja blokiranja.
# Zaključak#
Next.js aplikacije se brzo isporučuju, ali također izlažu endpointove visoke vrijednosti kroz API-je i Server Actions koje botovi vole iskorištavati. Implementirajte Next.js rate limiting kao slojeviti sustav, krenite s token bucket limitima koji su UX-friendly, i koristite WAF ili CDN pravila da zaustavite bučan promet prije nego dođe do vašeg origina.
Ako želite pomoć u dizajniranju pragova, implementaciji Redis-backed limita ili tuniranju bot zaštite bez štete za stvarne korisnike, javite se Samiodi. Pregledat ćemo vaše rute, preporučiti plan rollouta i implementirati monitoring kako biste limite mogli provoditi s povjerenjem.
FAQ
Osnivač i senior developer u Samiodi. 8+ godina iskustva u izradi React, Next.js, Flutter i n8n rješenja za klijente diljem Europe.
Više iz kategorije Web razvoj
Sve →Next.js SaaS kontrolna lista za onboarding: računi, dozvole, emailovi i probni periodi (App Router, 2026.)
Kontrolna lista za onboarding Next.js SaaS aplikacije spremne za produkciju, koja pokriva autentikaciju, organizacije, pozivnice, RBAC, transakcijske emailove i konverziju iz probnog u plaćeni plan uz praktične obrasce, biblioteke i uobičajene zamke.
React Query u velikim aplikacijama: invalidacija cachea, paginacija i obrasci mutacija za stvarne aplikacije
Najbolje prakse invalidacije cachea u React Queryju za aplikacije iz stvarnog svijeta: skalabilan dizajn query keyjeva, strategija invalidacije, optimistična ažuriranja, infinite queryji i pozadinski refetch u Next.js App Routeru.
React performanse u 2026.: profiliranje, memoizacija i obrasci renderiranja koji stvarno rade
Praktičan vodič korak po korak za profiliranje performansi i memoizaciju u Reactu u 2026.: kako dijagnosticirati spora sučelja uz React DevTools Profiler i why-did-you-render, odabrati prave obrasce renderiranja i izbjeći preuranjenu optimizaciju.
Trebate pomoć s projektom?
Gradimo prilagođena rješenja koristeći tehnologije iz ovog članka. Senior tim, fiksne cijene.
Povezani članci
Next.js Edge Runtime vs Node.js Runtime (Vercel i Cloudflare): Što pokretati gdje
Praktičan okvir za odlučivanje između Next.js Edge Runtime i Node.js Runtime u 2026., s konkretnim primjerima, ograničenjima i završnom matricom use-caseova.
Next.js pozadinski poslovi u 2026.: redovi, Cron i dugotrajni zadaci na Vercelu (i šire)
Praktičan vodič za izvođenje pozadinskog rada u Next.js-u u 2026.: Vercel Cron, ograničenja serverlessa, redovi s Upstashom i Redisom te worker servisi za dugotrajne zadatke. Uključuje kriterije odlučivanja, arhitekturne dijagrame i checklistu za produkciju.
Server Actions u Next.js App Routeru: produkcijski obrasci za validaciju, greške i optimistični UI
Vodič spreman za produkciju za validaciju formi u Next.js Server Actions uz Zod, strukturirano rukovanje greškama, progresivno poboljšanje, optimistični UI i ograničavanje brzine — plus kada odabrati Server Actions umjesto API ruta.