# Što ćete naučiti#
Ovaj vodič prikazuje production-ready pristup za A/B testiranje i feature flagove u Next.js-u s konzistentnom evaluacijom na serveru i klijentu, Edge specifičnostima i analitikom koja se stvarno veže uz poslovne ishode.
Otići ćete s arhitekturom koju možete implementirati odmah, tablicom usporedbe alata i playbookovima za rollout koje vaš tim može slijediti tijekom izdanja.
Ako usklađujete eksperimentiranje s performansama i vidljivošću u pretraživačima, pregledajte i zašto je Next.js jak za SEO te kako se uklapa u ponovljiv delivery pipeline u našem vodiču proces web razvoja.
# Temeljni koncepti: flagovi vs eksperimenti#
Feature flagovi i A/B testovi dijele sličnu mehaniku, ali imaju različitu namjenu.
- Feature flag: operativna kontrola i smanjenje rizika. Isporučite kod iza prekidača, pa ga postupno uključujete.
- Eksperiment: mjerenje utjecaja. Dijelite korisnike u varijante, provodite test do statističke pouzdanosti, pa odlučujete.
Najbrži način da napravite nered je tretirati eksperimente kao trajne flagove. Dobro pravilo je: flagovi su kratkog vijeka, dok je konfiguracija dugog vijeka.
Praktična taksonomija#
| Vrsta prekidača | Tipičan vijek | Primjer | Gdje evaluirati | Primarni rizik |
|---|---|---|---|---|
| Release flag | Dani do tjedana | Novi checkout flow | Server, middleware | SEO, hydration mismatch |
| Ops kill switch | Trajno | Onemogućiti payments provider | Server | Ublažavanje outagea |
| Permission flag | Trajno | Beta pristup po organizaciji | Server | Sigurnost, curenje podataka |
| Experiment flag | 2 do 6 tjedana | A/B tekst za cijene | Prvo server | Pogreške mjerenja |
| UI toggle | Tjedni do mjeseci | Nova animacija navigacije | Klijent | Flicker, nekonzistentnost |
🎯 Ključna poruka: Ako odluka mijenja HTML koji tražilice i korisnici vide pri prvom prikazu, mora se donijeti na serveru za početni zahtjev.
# Zahtjevi za robustan sustav flagova u Next.js-u#
Production implementacija trebala bi zadovoljiti ova ograničenja:
- 1Konzistentna dodjela kroz SSR, SSG, ISR, CSR navigaciju i refresh.
- 2Deterministička evaluacija za početni zahtjev, idealno na serveru.
- 3Edge kompatibilnost kada koristite Middleware ili Edge runtime.
- 4Brza evaluacija: provjera flaga treba biti jednocifren broj milisekundi na hot pathu.
- 5Sigurna analitika: pratite exposure i konverziju s istim assignment ključem.
- 6Upravljanje (governance): audit log, odobravanja i jasno vlasništvo nad time “tko smije što prebaciti”.
Zašto je ovo posebno važno u Next.js-u#
Next.js renderira na više mjesta: server, edge i browser. Ako vaša aplikacija donosi različite odluke u svakom od njih, dobivate:
- Upozorenja o hydration mismatchu i UI flicker.
- Korisnike koji vide varijantu A na SSR-u, a varijantu B nakon hydrationa.
- SEO rizik ako se indeksabilan sadržaj promijeni nakon učitavanja.
- “Ghost wins” u analitici jer se exposure krivo broji.
Povežite ovo s pouzdanošću: cijena debuggiranja nekonzistentnih varijanti je velika. U praksi timovi gube dane po kvartalu na ove probleme, osim ako arhitektura nije eksplicitna i provedena.
# Arhitektura: prvo server, klijent informiran#
Robusna arhitektura koristi server-first evaluaciju i zatim prosljeđuje rezultat klijentu kao stabilan “single source of truth”.
Preporučeni tok#
- 1Identificirajte korisnika (anonimni ID cookie, ID prijavljenog korisnika, org ID).
- 2Evaluirajte flagove na serveru za početni zahtjev.
- 3Persistirajte dodjelu u cookie ili session, posebno za eksperimente.
- 4Renderirajte SSR HTML na temelju odluke.
- 5Pošaljite snapshot flagova klijentu kako bi hydration koristio iste vrijednosti.
- 6Zabilježite exposure odmah kad se varijanta dodijeli, ne kasnije.
- 7Klijent koristi snapshot i ponovno validira samo kad eksplicitno osvježite flagove.
Podaci koje biste trebali persistirati#
| Polje | Svrha | Pohrana | Napomene |
|---|---|---|---|
anon_id | stabilan anonimni identitet | cookie | rijetko rotirati, držati first-party |
exp_checkout_v1 | dodjela eksperimenta | cookie | neka bude malo, postaviti expiry |
flag_new_nav | stanje release flaga | opcionalno | može biti samo na serveru ako ne treba klijentu |
flags_etag | validacija cachea | cookie ili header | pomaže izbjeći ponovno dohvaćanje |
⚠️ Upozorenje: Nemojte spremati cijeli JSON objekt flagova u cookie. Ograničenja veličine kolačića su stroga, a veliki cookies povećavaju veličinu requesta pri svakoj navigaciji i ruše performanse.
# Obrasci implementacije u Next.js-u (App Router)#
Feature flagove možete implementirati na više slojeva. Birajte prema tome što trebate kontrolirati.
Obrazac 1: Server Components i Route Handlers (najrobustnije)#
Koristite evaluaciju na serveru u App Routeru i proslijedite vrijednosti prema Client Components.
Prednosti: najbolja konzistentnost, najbolja kontrola SEO-a.
Nedostaci: zahtijeva korak evaluacije na serveru.
// app/lib/flags.ts
import { cookies, headers } from "next/headers";
export type FlagSnapshot = {
newCheckout: boolean;
checkoutExperimentVariant: "A" | "B";
};
export async function getFlagSnapshot(): Promise<FlagSnapshot> {
const cookieStore = cookies();
const anonId = cookieStore.get("anon_id")?.value ?? crypto.randomUUID();
// Example: deterministic bucketing for experiment
const variant = bucket(anonId, "exp_checkout_v1") < 0.5 ? "A" : "B";
// Example: release flag from environment or remote config
const newCheckout = process.env.FLAG_NEW_CHECKOUT === "true";
return { newCheckout, checkoutExperimentVariant: variant };
}
function bucket(subject: string, experimentKey: string): number {
// Deterministic 0..1 value
const data = new TextEncoder().encode(`${experimentKey}:${subject}`);
return (murmurhash3(data) % 10000) / 10000;
}
// Minimal murmurhash placeholder for brevity (use a real implementation in production)
function murmurhash3(_data: Uint8Array): number {
return 1337;
}U Server Componentu:
// app/(shop)/checkout/page.tsx
import { getFlagSnapshot } from "@/app/lib/flags";
import CheckoutA from "./CheckoutA";
import CheckoutB from "./CheckoutB";
export default async function CheckoutPage() {
const flags = await getFlagSnapshot();
if (!flags.newCheckout) return <CheckoutA />;
return flags.checkoutExperimentVariant === "A" ? <CheckoutA /> : <CheckoutB />;
}Obrazac 2: Middleware na Edgeu (brze odluke o routanju)#
Middleware je koristan kada flagovi utječu na routanje, geo, locale ili authentication gateove. Također može rano dodijeliti varijantu eksperimenta.
Prednosti: radi prije renderiranja, dobro za redirectove i rewriteove.
Nedostaci: ograničenja Edge runtimea, ograničene biblioteke, oprez s network pozivima.
// middleware.ts
import { NextResponse, type NextRequest } from "next/server";
export function middleware(req: NextRequest) {
const res = NextResponse.next();
const anonId = req.cookies.get("anon_id")?.value ?? crypto.randomUUID();
if (!req.cookies.get("anon_id")) {
res.cookies.set("anon_id", anonId, { httpOnly: true, sameSite: "lax", path: "/" });
}
const variant = simpleBucket(anonId) < 0.5 ? "A" : "B";
res.cookies.set("exp_checkout_v1", variant, { httpOnly: true, sameSite: "lax", path: "/" });
return res;
}
function simpleBucket(subject: string): number {
let h = 0;
for (let i = 0; i < subject.length; i++) h = (h * 31 + subject.charCodeAt(i)) >>> 0;
return (h % 10000) / 10000;
}
export const config = {
matcher: ["/checkout/:path*"],
};ℹ️ Napomena: Edge Middleware treba izbjegavati spora remote dohvaćanja flagova na svakom requestu. Ako trebate remote evaluaciju, agresivno cacheirajte i preferirajte kompaktne endpointove dizajnirane za Edge.
Obrazac 3: Flagovi samo na klijentu (koristite štedljivo)#
Evaluacija na klijentu je prihvatljiva za nekritične UI togglove koji ne utječu na indeksabilan sadržaj ili cijene.
Siguran obrazac je: server daje default, klijent može kasnije “nadograditi”.
// app/components/NewNavClient.tsx
"use client";
import { useEffect, useState } from "react";
export function NewNavClient({ enabledByServer }: { enabledByServer: boolean }) {
const [enabled, setEnabled] = useState(enabledByServer);
useEffect(() => {
// Optional: refresh from remote config after hydration
// Keep it additive: never break SSR consistency
setEnabled(enabledByServer);
}, [enabledByServer]);
return enabled ? "New nav" : "Old nav";
}# Edge specifičnosti: performanse, privatnost i determinističnost#
Edge je privlačan jer smanjuje TTFB računajući bliže korisniku. Ali nameće kompromise.
Što se tipično “lomi” na Edgeu#
| Tema | Što se dogodi | Ublažavanje |
|---|---|---|
| Teški SDK-ovi | raste bundle size, cold startovi se pogoršavaju | koristite lagani fetch klijent ili evaluaciju na serveru |
| Remote pozivi za flagove | dodatna latencija po requestu | cache na CDN-u, koristite ETag, osvježavajte u intervalima |
| Nedeterministička dodjela | korisnici “skaču” između varijanti | persistirajte variant cookie, stabilan bucketing |
| Ograničenja privatnosti | regionalna pravila consent-a | dodjeljujte eksperimente tek nakon consent-a gdje je potrebno |
| Preveliki cookies | veći request headeri | minimalni identifikatori, spremati samo ključeve eksperimenata |
💡 Savjet: Ako trebate personalizaciju na Edgeu, napravite zaseban endpoint “flags for edge” koji vraća samo nekoliko ključeva potrebnih za routanje, s malim JSON payloadom i cache headerima.
# Analitika: ispravno praćenje exposurea i konverzije#
A/B testiranje je ponajviše higijena analitike. Ako krivo brojite exposure, možete “dokazati” bilo što.
Minimalni event model#
Pratite ove evente:
experiment_exposure: šalje se kada korisnika dodijelite varijanti.conversion: šalje se na poslovnu akciju koja vam je bitna.
Oba eventa moraju uključivati:
- ključ eksperimenta
- varijantu
- stabilni subject ID, poput
anon_idili user ID - timestamp
- opcionalni kontekst, npr. plan, uređaj, država
| Polje | Primjer | Zašto je važno |
|---|---|---|
experiment_key | exp_checkout_v1 | povezivanje exposurea s konverzijom |
variant | A | izračun lifta |
subject_id | anon_3f2... | deduplikacija korisnika |
exposure_id | uuid | sprječavanje dvostrukog brojanja |
page | /checkout | debug segmentacije |
consent | analytics_allowed | usklađenost (compliance) |
Kada okidati exposure#
Exposure okidajte u najranijoj točki u kojoj korisnik može biti “pod utjecajem”.
- Ako renderirate varijantu B na serveru, zabilježite exposure na serveru u tom requestu.
- Ako eksperiment mijenja samo widget na klijentu, zabilježite exposure kad se widget mounta, ali neka dodjela bude server-provided.
Čest benchmark od analytics vendora je da client-side tracking može biti blokiran kod 10 do 30 posto korisnika zbog ad blockera i privacy postavki. Ako vam je eksperiment osjetljiv na prihod, želite server-side exposure gdje je moguće, a gubitak trackinga trebate mjeriti usporedbom server logova i analytics brojki. Za prakse observabilityja koje to podržavaju, pogledajte naš vodič za observability web aplikacija.
Primjer: server-side logiranje exposurea (Route Handler)#
// app/api/experiments/exposure/route.ts
import { NextResponse } from "next/server";
export async function POST(req: Request) {
const body = await req.json();
// Validate and forward to your analytics pipeline (Segment, GA4, PostHog, BigQuery, etc.)
// Keep payload minimal and avoid PII.
console.log("exposure", body);
return NextResponse.json({ ok: true });
}Client poziv s dodijeljenim snapshotom:
// app/lib/trackExposure.ts
"use client";
export async function trackExposure(payload: {
experiment_key: string;
variant: string;
subject_id: string;
exposure_id: string;
}) {
await fetch("/api/experiments/exposure", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify(payload),
keepalive: true,
});
}# Alati: managed platforme vs open source i self-hosted#
Odabir alata uglavnom ovisi o governanceu, složenosti targetiranja i koliko infrastrukture želite posjedovati.
Tablica usporedbe#
| Vrsta alata | Primjeri | Prednosti | Kompromisi | Najbolje za |
|---|---|---|---|---|
| Managed feature flagovi + eksperimentiranje | LaunchDarkly, ConfigCat, Optimizely, Vercel Feature Flags integrations | odobravanja, audit log, targetiranje, SDK-ovi, visoka dostupnost | kontinuirani trošak, rizik vendor lock-ina, “težina” SDK-a | veći timovi, regulirani workflowi |
| Product analytics s eksperimentima | PostHog, Amplitude, Mixpanel | ujedinjeni exposure i konverzija, funnelovi, cohorti | može trebati pažljiva SSR integracija, cijena na velikoj skali | product-led timovi koji optimiziraju UX |
| Open source feature flagovi | Unleash, GrowthBook | self-host, predvidljiv trošak, snažno targetiranje | vi vodite infra, HA, backup | timovi s DevOps zrelošću |
| Lagani self-built | env flagovi, remote JSON na CDN-u, tablica u bazi | minimalan trošak, potpuna kontrola, brzo | governance i analitika su na vama | jednostavni rolloutovi, mali timovi |
Praktičan checklist za odluku#
Odaberite managed ako trebate barem dva od ovoga:
- workflow odobravanja i audit povijest
- da ne-inženjeri prebacuju prekidače
- složeno targetiranje poput org plan, regija, uređaj, cohort
- ugrađenu analizu eksperimenata
Odaberite self-host ili lightweight ako:
- flagovi su uglavnom release togglovi i kill switchevi
- eksperimenti su rijetki i jednostavni
- već imate snažnu internu analitiku i observability
⚠️ Upozorenje: Mnogi timovi podcjenjuju troškove “human toolinga”. Jeftin self-built sustav postane skup kad vam trebaju permisije, povijest, staged rolloutovi i incident-safe kill switchevi.
# Sigurna uvođenja: playbookovi koje tim može provoditi#
Flagovi briljiraju kada su upareni s ponovljivim rollout ritualima. Ovi playbookovi smanjuju rizik u produkciji i ubrzavaju donošenje odluka.
Playbook 1: Progresivna isporuka za rizičnu UI promjenu#
Koristite kada isporučujete veliku promjenu flowa poput checkouta, onboardinga ili pricing UI-ja.
- 1Isporuka iza release flaga default off.
- 2Uključite samo internim korisnicima, npr.
@company.comaccountima. - 3Uključite za 1 posto prometa kroz 24 sata.
- 4Povećajte na 10 posto, zatim 25 posto, zatim 50 posto, uz praćenje metrika na svakom koraku.
- 5Idite na 100 posto, zadržite flag 1 do 2 tjedna, pa uklonite kod.
Metrike koje treba pratiti po koraku:
| Metrika | Zašto | Tipičan prag za alarm |
|---|---|---|
| Stopa konverzije | poslovni utjecaj | pad veći od 2 posto relativno |
| Stopa grešaka | stabilnost | porast veći od 0,5 posto apsolutno |
| Web vitals | UX i SEO | LCP se pogorša za više od 200 ms |
| Support tiketi | kvalitativni signal | skok iznad baselinea |
Povežite rollout s vašim procesom isporuke: flag nije zamjena za QA i disciplinu izdanja. Ako vašem timu nedostaje strukturiran pristup, uskladite se s konzistentnim pipelineom kao u našem vodiču proces web razvoja korak po korak.
Playbook 2: Kill switch za third-party ovisnosti#
Koristite kada outage vendora može slomiti ključne flowove.
- 1Napravite server-evaluirani ops flag poput
payments_provider_enabled. - 2Default on.
- 3Implementirajte siguran fallback, npr. onemogućite metodu plaćanja i prikažite jasnu poruku.
- 4Dokumentirajte tko ga može prebaciti i koliko brzo, uključujući pokrivenost po vremenskim zonama.
- 5Mjesečno uvježbajte prebacivanje u stagingu.
Operativni dobitak: mean time to mitigate postaje minute, ne sati.
Playbook 3: A/B test s čistom analitikom#
Koristite kada trebate odluku, ne samo rollout.
- 1Definirajte metriku uspjeha i guardrailove prije pisanja koda.
- 2Dodijelite varijantu na serveru koristeći deterministički bucketing.
- 3Persistirajte dodjelu u cookie kako biste spriječili re-bucketing.
- 4Zabilježite exposure jednom po subjectu.
- 5Pokrećite minimalno kroz prozor koji pokriva tjednu sezonalnost, najčešće 14 dana za B2C.
- 6Zaustavite ranije samo ako se guardrailovi pokvare ili je lift “ogroman”.
Jednostavan baseline za planiranje sample sizea je: manji očekivani lift zahtijeva veće uzorke. Ako očekujete 1 posto relativnog poboljšanja, tipično trebate velik volumen prometa da biste to detektirali s pouzdanošću. Čak i ako koristite alat koji tvrdi da automatski računa značajnost, provjerite vlastitim sanity checkovima: broj exposurea, ravnotežu varijanti i integritet konverzija.
💡 Savjet: Dodajte “experiment health” dashboard: broj exposurea, postotak split-a varijanti, lag konverzija i tracking loss. To otkriva pokvarene eksperimente u roku sati, a ne tjedana.
# Česte greške u Next.js feature flagovima i eksperimentima#
- 1Client-only zamjena SSR sadržaja: tražilice i korisnici vide jedno, hydration pokaže drugo.
- 2Re-bucketing na svakom requestu: korisnici skaču između varijanti, rezultati se kontaminiraju.
- 3Korištenje samo user ID-ja: odjavljeni korisnici postaju neuhvatljivi; prvo koristite
anon_id, pa zatim merge. - 4Previše dugovječnih flagova: raste kompleksnost koda; timovi zaborave zašto flag postoji.
- 5Bez vlasništva: flagovi bez vlasnika se nikad ne uklone i postanu production mine.
Praktično pravilo: ako je flag stariji od 60 dana, mora se pregledati radi uklanjanja ili pretvaranja u trajnu konfiguraciju.
# Ključne poruke#
- Flagove evaluirajte server-first za sve što utječe na HTML, routanje, SEO, cijene ili sigurnost, i proslijedite stabilan snapshot klijentu.
- Dodjelu eksperimenta persistirajte u malom cookieju kako biste spriječili re-bucketing kroz SSR, CSR navigaciju i refresh.
- Edge Middleware koristite za routanje i ranu dodjelu, ali logiku držite laganom i izbjegavajte remote SDK pozive po requestu.
- A/B testove pratite s eventovima exposure i conversion vezanima uz stabilan subject ID, te pratite tracking loss kroz observability.
- Alate birajte prema governance potrebama: managed platforme za odobravanja i targetiranje, self-hosted ili lightweight za jednostavne release flagove.
- Provodite ponovljive rollout playbookove s jasnim guardrailovima i metrikama, a zatim uklanjajte flagove kako bi codebase ostao čist.
# Zaključak#
Feature flagovi i eksperimenti nisu samo “toggleri” u Next.js-u. To je arhitekturna odluka koja utječe na SEO, performanse, integritet analitike i operativnu sigurnost.
Ako trebate pomoć oko implementacije server-first sustava flagova, Edge-safe evaluacije i analitike kojoj možete vjerovati, Samioda može osmisliti rollout strategiju i isporučiti infrastrukturu zajedno s vašim timom. Krenite pregledom trenutnog renderiranja i postavki mjerenja, a zatim nas kontaktirajte kako bismo isplanirali sigurnu migraciju i roadmap vaših prvih eksperimenata.
FAQ
Više iz kategorije Web razvoj
Sve →React Query vs SWR u Next.js App Routeru: Kada koristiti koji (i kako izbjeći dvostruko dohvaćanje)
Praktična usporedba za 2026. React Queryja i SWR-a unutar Next.js App Routera — modeli cacheiranja, SSR i RSC kompatibilnost, mutacije, optimistična ažuriranja, DX i provjereni obrasci za sprječavanje dvostrukog dohvaćanja.
Next.js učitavanje datoteka kako treba: izravno na S3 i Cloudflare R2 s presigned URL-ovima, validacijom i sigurnošću
Praktičan vodič za 2026. o izradi sigurnih i pouzdanih izravnih uploadova u object storage u Next.js App Routeru uz presigned URL-ove, serversku validaciju, rukovanje ponovnim pokušajima i opcionalno antivirusno skeniranje.
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.
Trebate pomoć s projektom?
Gradimo prilagođena rješenja koristeći tehnologije iz ovog članka. Senior tim, fiksne cijene.
Povezani članci
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.
Observabilnost web aplikacija: praktični vodič za logove, metrike i tracing za React i Next.js
End-to-end, produkcijski spremna observability postava za React i Next.js: praćenje grešaka, nadzor performansi, strukturirani logovi, tracing, nadzorne ploče i alerti koji hvataju stvarne probleme.
React Query vs SWR u Next.js App Routeru: Kada koristiti koji (i kako izbjeći dvostruko dohvaćanje)
Praktična usporedba za 2026. React Queryja i SWR-a unutar Next.js App Routera — modeli cacheiranja, SSR i RSC kompatibilnost, mutacije, optimistična ažuriranja, DX i provjereni obrasci za sprječavanje dvostrukog dohvaćanja.