Skip to content
Services · Build

Next.js is the default here because it is boring in the right places. The work is in the places it is not.

What this is

The framework we build on, and what it costs to run.

Business Report, Khendo FM and COFEK run on the Next.js App Router with Sanity as the content store and Vercel underneath. So does this site. That is not a preference for novelty. Server rendering is what makes a page readable on a slow connection before any JavaScript arrives, and a framework the next developer already knows is a maintenance decision made in the client’s favour.

What a Next.js build actually involves is mostly decisions the framework leaves open. Which routes are static, which are rendered per request, and which are cached and for how long. How images are served, because the default optimiser is metered and will happily re-process a picture a content CDN already resized. How redirects from an old site are expressed and verified. Where the content lives, so that an editor can publish without a deploy.

The defaults are tuned for a developer on a fast machine. Left alone they produce a site that is quick in a demo and expensive or slow in production, usually both at once, and the invoice is the first anybody hears of it. We set those decisions deliberately, write down why, and measure the result on the devices the audience actually holds.

We also take over Next.js sites somebody else built. The usual reasons are a hosting bill that grew with the size of the site rather than its traffic, a migration that dropped its redirects, or a content model nobody can publish into without a developer. Each of those is a structural decision, not a bug, and each has a known fix.

Redirects are the example that comes up most. Next.js emits a permanent redirect by default and that is fine, but a redirect map is a hypothesis until each entry has been requested against the deployed site and the response read: one permanent hop, the destination the map predicted, and a 200 at the end of it. We run that against a preview deployment before cutover and against production immediately after, because the two differ in exactly the ways that break redirects.

What’s involved

App Router architecture
Static, server-rendered and cached routes decided per page rather than defaulted, with the reasoning recorded.
Sanity content modelling
Documents, references and preview, so the people who publish are not waiting on the people who deploy.
Image and asset pipeline
One transformation, at the CDN that already does it, with the loader preserving the crop ratio across the srcset.
Vercel cost and caching review
What the metered services are billing for, which of it is duplicated work, and the cache lifetimes that stop it.

How it usually goes

  1. Read the existing site

    Routes, content, redirects, and the bill. The bill is a specification too.

  2. Decide rendering per route

    Static where it can be, dynamic where it must be, cached in between.

  3. Build and migrate

    Content into Sanity, URLs preserved, redirects verified against production.

  4. Measure and hand over

    Field data on real devices, the invoice after a month, and a runbook for whoever runs it next.

What we won’t do

  • We will not choose Next.js for a site that is three static pages. A framework is a maintenance commitment, and a small site does not need one.
  • We will not ship the image optimiser on its defaults in front of a CDN that already resizes.
  • We will not quote a Lighthouse score as the deliverable. It is an instrument, not a result.
Start here

Tell us what’s load-bearing.

One email, no form. Describe the part that breaks if it isn’t right. If it isn’t for us, you’ll get a straight no and a reason, usually within the week.

A reply from a person

Usually within the week, and never an auto-response.

A straight no, with the reason

If it is not for us we would rather be useful in one paragraph.

A call before a proposal

To find the real constraint first, which is usually not the one in the brief.