Framework guides: Next.js, Vite, edge runtimes, and plain Node
The same client, wired up correctly in four different environments — and the one Next.js mistake that quietly defeats the RPC bridge from the last two posts.
15 posts
The same client, wired up correctly in four different environments — and the one Next.js mistake that quietly defeats the RPC bridge from the last two posts.
Deny-by-default is one layer. Here's every other threat the bridge is built to handle — prototype pollution, CSRF, and the line between what it secures and what your code still has to.
Import your normal API client into a client component and check the Network tab. This is the architecture that stops that from happening.
One BigInt makes JSON.stringify throw, so your logger drops every other field too. What I measured, and a safe() helper that keeps Dates and Errors intact.
Batched logs sit in memory until a timer fires. Serverless freezes your function the moment it responds. Here is what I measured, and the one-line fix.
Everyone says console.time() breaks under concurrency because the second call overwrites the first. I tested it in Node, Bun and Deno, and that is not what happens. The second timer is thrown away, the fast request reports the slow request's duration, and the slow request reports nothing at all.
I set LOG_LEVEL to turn on debug logs for one feature. Nothing appeared. The rules were spelled correctly — they were just in the wrong order. Here is what I measured, and the rule that tells you which order is right.
How to resolve the right tenant ID per request in a shared SSR client — and why ambient context beats passing tenantId through every function call.
window.onerror is the answer everyone gives. It never fires for a broken image, and the next library that loads can delete yours. Here is what to use instead, on the client and on the server, tested in a real browser.
A crash at chunks/page.js:1:518 tells you nothing. Source maps turn it back into checkout.ts:3:49. Here's how the lookup works, and the one case where it hands you a real-looking line number that is completely wrong.
AsyncLocalStorage lets you stamp a request ID onto every log line without passing it through every function. But it can fail without throwing a single error — so your logs just quietly lose the ID. Here are the three cases I reproduced, and the two-minute check that catches them.
A component that logs on every render can fire dozens of network requests per second. Here's how per-level throttle, debounce and rate-limit policies fix it — including the one-word config typo that silently brings the flood right back.
The problem with console.log in the browser, why a naive 'POST logs to the server' endpoint is a security hole, and how @developerehsan/nextjs-logger solves both with one import.
Before touching config options, understand the client, the modules, and the pipeline — the three ideas everything else in api-client is built on.
Every project I ship ends up with the same auth-retry-cache logic copy-pasted and slightly broken. Here's why I finally turned that pattern into a real package.