Next.js frontend development: SSR, SSG, ISR, and App Router

Slow response times and drops in search rankings usually come down to how catalog pages are rendered. We build Next.js frontends end to end: we configure server-side rendering, static pages, and cache revalidation so pages respond faster and rankings grow. Let's discuss your task and come back with a plan and estimate.

Development and maintenance of all types of websites:

Informational websites or web applications
Business card websites, landing pages, corporate websites, online catalogs, quizzes, promo websites, blogs, news resources, informational portals, forums, aggregators
E-commerce websites or web applications
Online stores, B2B portals, marketplaces, online exchanges, cashback websites, exchanges, dropshipping platforms, product parsers
Business process management web applications
CRM systems, ERP systems, corporate portals, production management systems, information parsers
Electronic service websites or web applications
Classified ads platforms, online schools, online cinemas, website builders, portals for electronic services, video hosting platforms, thematic portals

These are just some of the technical types of websites we work with, and each of them can have its own specific features and functionality, as well as be customized to meet the specific needs and goals of the client.

Frequently Asked Questions

Next.js development: where the bottleneck is and what breaks

The rendering bottleneck almost always looks the same: the server returns an empty shell, while all the logic — catalog filters, price substitution, list loading — runs in the browser.

On an average mobile device, this means seconds of a white screen, and the rise in bounce rates begins before metrics have time to show it.

Slow page loading is rarely explained by a single heavy file. Usually it is accumulated client-side code: every new block, widget, and external counter is connected to all pages at once because there is no route-level splitting.

The bundle grows monotonically — and along with it grow the time to first render and the cost of every change.

A separate failure is empty pages in search results. If content is inserted by a script after loading, the crawler indexes a placeholder: a title without text, a catalog without items, an article without paragraphs.

This is a direct loss of search positions for queries where the direction previously held top rankings, and winning them back is more expensive than not losing them.

All three symptoms have one cause — an architectural fork: how much work is offloaded to the server, what is cached and for how long, and what truly must live in the browser.

In Next.js, these are rendering modes and the boundaries between server and client components, not the choice of library. We explain how this is addressed and what changes in the numbers.

What server-side rendering delivers: the effect on metrics and search results

First render speed

Server-side rendering returns the markup ready-made, so the browser displays content without waiting for scripts to load and execute.

Time to first render is reduced to a single network request, and on a median mobile network the gap with a client-side build is immediately noticeable.

Page indexing

The search crawler receives the same HTML as the visitor, with no queue for script execution. The share of pages in the index grows: empty responses and duplicates that appeared when content was assembled in the browser disappear.

Metadata and structured data are generated on the server, so snippets are stable for every product page and section.

Load on the client device

The server sends computed markup rather than data for assembling it, so low-end phones and budget laptops spend less CPU time and battery. Only interactivity remains on the client — forms, filters, and navigation without page reloads.

Resilience to peak traffic

Ready and cached responses leave the edge layer, bypassing the application — a traffic spike does not turn into a queue on the backend. Pages are updated on a schedule or by event, so data stays current under load, and if the source degrades, the cache continues to serve content.

Next.js development: SSR, SSG, ISR, and client-side rendering

In the App Router, the delivery mode is set not for the entire application but at the route segment level: a catalog can be served statically, an account dashboard can be rendered on the server for every request, and a news section can update on a schedule.

So “choose one mode for the project” is the wrong question: the decision is made separately for each page type.

From there, the choice comes down to a trade-off between time to first byte, data freshness, and server load.

Static generation and ISR serve ready-made HTML without hitting the application server and withstand traffic, but show data as of the last update; SSR is always current, but every request costs computation, and user-specific blocks without server-side rendering appear only after hydration.

Summary of modes

Mode When it fits Limitations
SSG Landing pages, documentation, reference pages: content changes on release A change requires a rebuild; personalization is unavailable
ISR Catalog, product pages, news: content changes, but not by the second Until updated, the previous version may be served; cache size grows
SSR Account dashboard, cart, search results, authenticated pages Response depends on the server and external sources; higher load
Client-side rendering Widgets and interactive panels inside an already rendered page This block has no ready-made HTML for search engines; data arrives with a delay

In practice, modes are combined within a single route tree: the page is served statically, while its personalized blocks are loaded separately.

Implementation stages: from audit to handover to engineers

The order of stages is determined by risks, not convenience: first we remove uncertainty about the current code, then change routing, and only after that address load and acceptance.

At each step we record the before and after state — project acceptance relies on measurements, not impressions.

  1. Frontend audit. We review the structure of pages and routes, data sources, and the amount of code sent to the browser. The output is a map of bottlenecks with an assessment of their impact on delivery speed.
  2. Route and data scheme. We classify pages by mode: static, server build per request, update on a schedule or event. For each route — the data source and behavior when it is unavailable.
  3. Rendering setup. We move the scheme into the App Router, mark server and client components, and define update rules and targeted tag-based invalidation so that editing one entity does not reset the entire cache.
  4. Zero-downtime migration. New routes run in parallel with old ones, responses are compared on live traffic, and switching happens as they match.
  5. Load testing. We measure time to first byte, error rate, cold start, and behavior when external services fail.
  6. Project acceptance. We compare before and after metrics, record a route checklist, a rollback scenario to the previous version, and a content update procedure.
  7. Handover to engineers. Architecture documentation, route scheme, access credentials, and procedures — the team can run the project on its own going forward.

Project artifacts: repository, schemas, procedures

The project is handed over not as an archive of files but as a working system: with it, a new engineer can set up the environment and ship a release without tracking down the original author. Below is a list of artifacts that remain with the client along with the source code.

  • Repository and route structure — segment tree, nested layouts, loading and error boundaries. It immediately shows which address is served statically, which is rendered on the server, and which lives on the client.
  • Route configuration — redirects, rewrites, response headers, and access rules are collected in one place rather than scattered across handlers.
  • Data flow scheme — where data comes from, where the server layer is, where the client layer is, which requests are cached, and which go directly to the source.
  • Caching policies — for each route, the delivery mode, record lifetime, and event-based reset condition are fixed, not timer-based. This is what most often breaks during changes without documentation.
  • Release and deployment procedure — build order, mandatory checks, branching scheme, deployment to the test environment, and rollback to the previous release.
  • Frontend maintenance instructions — dependency updates, behavior when data and cache diverge, and control points when the build fails.
  • Project documentation — environment scheme, variables, access procedure, log of known limitations, and a walkthrough handover for the client’s team.

Case study: a catalog with a million pages began responding noticeably faster

A catalog with a million product pages was rendered on the server for every request: peak response time reached 1.9 s, search crawlers crawled sections slowly, and fewer than half of the product pages remained in the index.

On sale days, when traffic grew sixfold, the service began returning errors, and part of the audience went to competitors.

We separated content by mode: categories and popular product pages are served statically, the rest on request with background revalidation according to recheck rules, and personalized blocks (regional availability, price with a loyalty card) were moved into client components.

The storefront was rebuilt on Next.js server components and streaming, and the server side of the catalog was covered by a cache with targeted invalidation on product change notification: instead of a full 40-minute rebuild, only the affected pages are updated.

What changed in metrics: 95th percentile server response time — from 1.9 to 0.3 s, share of pages in the search index — from 43% to 91%, organic traffic grew by about 2.3x over the quarter.

The service now handles a sixfold sale peak without errors or degradation, and mass price updates no longer require a full catalog rebuild.

Feedback from the client’s CTO: “The catalog is no longer a bottleneck — sales and price updates no longer require manual intervention from the on-call team.”

How does server-side rendering differ from static generation?

The difference is based on when the HTML is generated. Static generation prepares pages once, at build time: each request serves an already-built file from the cache on the node closest to the user.

Server-side rendering assembles the markup at request time — for a specific user and with current data.

It is convenient to look at the difference along three axes: data freshness on the page, behavior under load, and infrastructure requirements.

In Next.js, it is not a hard choice between two options: incremental regeneration serves the page from cache while triggering regeneration in the background on an interval or on demand when content changes.

Delivery mode When it fits Limitations
Static generation Catalog, landing pages, documentation — data rarely changes Content edits require a rebuild; personalization is unavailable
Rendering on request Account dashboards, stock and prices for a specific user Every request consumes application resources; peaks require spare capacity
Incremental regeneration Content pages with frequent edits Cache and lifetime must be managed: a staleness window remains

Under load, the behavior differs fundamentally. Static generation withstands peaks through caching responses at the network edge — the number of requests almost never reaches the application, and infrastructure cost grows slowly.

Rendering on request hits the data every time, so capacity is planned for traffic: an intermediate-layer cache helps, but it does not work for personalized responses.

That is why in practice modes are separated by route rather than choosing one for the entire project: static generation for public sections, rendering on request for personalized ones, and incremental regeneration for catalogs with regular edits.

Concerns about the App Router, cache, and routing

Concerns before starting are usually technical, and they are resolved during design, not in production. Below are the questions most often raised when the team has already chosen Next.js and is discussing the move to the App Router.

Can we migrate in parts without rewriting the entire site?

Yes. We bring up new sections on the App Router, while old routes continue to work and are migrated by zones, one at a time. The data, styles, and markup layer remains unified, so visitors see no seams, and releases do not stop during the transition.

Will the cache start serving old prices and stock levels?

We cache by data type: texts and the catalog — for a long time, prices, availability, and personalized blocks — with a short lifetime or no storage at all. Reset is tied to an event: when a product changes, only related pages are regenerated, not the entire site.

We have our own server and deployment — will we have to rebuild everything?

As a rule, no. The application is deployed in a container behind your proxy; the domain, certificates, and load balancing stay in place; only the build steps change. We discuss static delivery plans before the start — the set of available rendering modes depends on this.

External services respond slowly — will the site wait?

No. We fetch external system responses on our side, with a timeout and a fallback value: the visitor gets a ready page, not a wait for someone else’s server. If the service is unavailable, we show a correct variant and log the failure for review.

Let’s discuss the task: we’ll come back with a plan and estimate

You can start with a discussion of the task — a detailed technical specification is not required at the outset.

It is enough to describe the product and how it should work: which pages and sections are needed, where data comes from, whether delivery via server-side rendering is needed or static generation with background updates is sufficient.

It is useful to see the current code or a prototype, if one exists, and to get access to the repository, content management panel, and test environment.

If there is no project yet, a map of sections, authorization requirements, and examples of interfaces that are close to your logic will be enough.

As a result, you receive:

  • an App Router route map: which pages are rendered on the server and which are built statically;
  • a data source scheme and cache update rules;
  • a stage-by-stage work plan with order and dependencies;
  • an estimate of effort and timelines for each stage;
  • team composition and points where your decision is needed;
  • a list of risks and the rollback procedure to the previous state.

This is a working document that shows where the project will start and what you will receive at each step. Describe the task in any convenient form — we will come back with a work plan and project estimate, and we will clarify details if needed on a call with engineers.

Our competencies:

Latest works

  • Development of a web application for FEEDME
    Development of a web application for FEEDME
    1393
  • Development of an online store for the company FURNORO
    Development of an online store for the company FURNORO
    1368
  • Development of a web application for Enviok
    Development of a web application for Enviok
    1139
  • CRM development for Chasseurs
    CRM development for Chasseurs
    1152
  • Website development for SBH Partners
    Website development for SBH Partners
    1231
  • Website development for Red Pear
    Website development for Red Pear
    641