Ask

Jo Petrakis

@wrangler_dev_jo

Junior-ish developer, about eighteen months in, building a side product on D1 and Queues. I ask more questions than I answer and I try to write up whatever finally worked.

0 credit Newcomer

From answers
0
From questions
0

Joined September 17, 2025 · 0 followers · 0 following

Next.js 16.3 preview: "use cache" breaks i18next with Cannot access cookies() or headers() in "use cache"

On the library question, honestly: i18next was not designed around this constraint and you feel it. Two data points rather than a recommendation.

next-intl has been publishing guidance for the Cache Components world, and there is an open issue where its Link still triggers a request-context lookup inside a cached scope even when you pass the locale explicitly, so it is not a finished story either. Compile-time approaches like paraglide sidestep the whole problem because messages become plain imports with nothing dynamic to trip over.

I have only run the compile-time route on a small app. Before migrating anything large, go and read the current open issues for whichever one you pick, because this is all moving week to week.

6 · in/app-router ·

next 15 upgrade turned every fetch uncached and my pricing api bill went 16x

Separate from fixing the config: if that vendor charges per call, do not let a framework cache be the only thing between you and the invoice. Stick a small cache in front that you own - KV, Redis, a table, anything with an explicit TTL you can read at 3am. Framework caching defaults are going to keep changing across majors and your vendor contract is not.

18 · in/app-router ·

middleware runs twice per navigation and my rate limiter 429s real users

Both. Exclude prefetches now, then move the limiter.

The matcher takes missing, so you can keep prefetch requests out entirely:

export const config = {
  matcher: [{
    source: '/dashboard/:path*',
    missing: [{ type: 'header', key: 'next-router-prefetch' }]
  }]
}

But the deeper issue is that you are counting page views, and page views are not the thing you are protecting. Nobody abuses your app by looking at the dashboard. Put the limiter on the route handlers and server actions that write or that call something expensive, keyed on the user id rather than the IP, and let navigation be free. Your office customers behind one NAT will thank you too.

44 · in/app-router ·

vercel or a $12 vps for an app router app at 300k requests a month

Three things bite, in this order:

  1. ISR cache is on local disk by default. One box, fine. The moment you run two containers for a zero-downtime deploy they each have their own cache and users see pages flip between two versions. You need a shared cache handler pointed at Redis, which is another service to run.
  2. Image optimisation is CPU and disk. sharp will happily eat a whole vCPU resizing a 4000px phone photo, and the optimised images accumulate on disk until something fills up at 2am. Cap the sizes you allow and put a real cache in front.
  3. You become the person who renews the certificate. Caddy makes that mostly automatic, which is why I use it over nginx for this exact setup.

None of it is hard. It is about two evenings up front and an hour a month afterwards. If that hour is worth more to you than $20, stay managed.

38 · in/app-router ·