ATS Global
Next.js · React · Headless front ends

Next.js development, proven on our own website

The site you are reading is a Next.js 16 application. Its blog and case studies are written in Frappe, fetched over REST, cached by tag and refreshed the moment an editor publishes. We build the same thing for clients: public sites and portals that load fast, rank, and read their content from the platform you already run — Liferay DXP, ERPNext or your own APIs.

Appistoki logo
Capgemini logo
Careedge Global logo
CES logo
Cignex logo
EngineersMinds logo
Fulcrum logo
IGT Solutions logo
InfoBeans logo
ITC logo
Knowarth logo
Larsen & Toubro logo
Lister logo
Ness logo
NetSol logo
PodEngine logo
Raising logo
Sharp logo
Triton logo
Wego logo
Wipro logo
Xebia logo
94mobile Lighthouse performance on this site's home page, up from 58
2.8 smobile LCP in the same lab test, down from 9.4 s
47case studies this site renders from Frappe, refreshed on publish
24old-site URLs Google still had indexed, 301-redirected to their closest new page

Next.js development services

What we build with Next.js

Sites and applications where the first visit matters: someone arrives from a search result, a shared link or an ad, and the page has to be fast, indexable and correct before they sign in — if they ever do. For screens that live entirely behind a login, plain React is often the simpler choice.

Corporate & marketing sites

Service pages, case studies, blogs and landing pages rendered on the server, with metadata, structured data and a sitemap generated from the same content.

Headless CMS front ends

Next.js reading content from Liferay DXP, Frappe or another headless CMS over REST or GraphQL, with editors publishing in the tool they already use.

Customer portals & SaaS

Public pages and signed-in areas in one application: server-side sessions, role-based access and API keys that never reach the browser.

Core Web Vitals & performance

Server components to keep JavaScript down, font subsetting, image sizing, deferred third-party scripts and caching that survives real traffic.

Technical SEO in the framework

Canonical URLs, JSON-LD, sitemaps, RSS, Open Graph images, redirects for old URLs and IndexNow — generated by the build, not maintained by hand.

Migrations to the App Router

Pages Router, Create React App and Gatsby sites moved to the App Router route by route, with URLs, redirects and rankings preserved.

Where Next.js fits

When Next.js is the right framework, and when it is not

Next.js earns its place when pages have to be good before anyone signs in. It renders React on the server, so search engines and link previews see complete HTML, the first paint does not wait for a JavaScript bundle, and each route can choose its own strategy: built once at deploy, regenerated when content changes, or rendered on every request when it depends on who is asking.

It is not the answer to everything. An internal dashboard or a back-office tool used only by signed-in staff gains little from server rendering, and a React application on a Vite build is simpler to run. A site that is almost entirely static content with little interactivity can be lighter still on a static-site generator. And a portal already running on Liferay DXP may be better served by React inside the portal than by a new front end beside it.

The decision comes down to who the first visitor is, where the content lives and who maintains the code afterwards — and we write the recommendation down with its reasons before the build starts.

  • Public sites that depend on search, shared links or paid traffic
  • A headless CMS or ERP that should keep owning the content
  • Products with public pages and a signed-in area in one codebase
  • Teams that want React skills to carry over to the server

Case study: atsglobal.in

How our own Next.js site is built

atsglobal.in runs on Next.js 16 with the App Router, React 19, TypeScript and Tailwind CSS. Pages are server components; client-side code is limited to the parts that are actually interactive, such as menus, carousels and the chat assistant.

Content does not live in the codebase. The blog and every case study are authored in Frappe — the same platform that runs our own HR and accounts — and read over its REST API. Each fetch is cached under a tag for an hour; when an editor saves a post or a case study, a Frappe webhook calls a secret-protected revalidation endpoint, the tag is purged, and the listing, the detail page, the sitemap, the RSS feed and the related-content strips on service pages all re-render on their next request. If Frappe is unreachable, the case studies fall back to a committed copy of the content instead of failing.

It is deployed as a standalone Node.js server in a Docker image — a multi-stage build on Node 22, running as a non-root user — on a VPS behind nginx with HTTP/2. There is no platform lock-in: the same image would run on AWS, Azure or any container host.

  • Next.js 16 App Router, React 19 server components, TypeScript, Tailwind CSS
  • Frappe as the CMS for the blog and case studies, read over REST
  • Tag-based caching, purged by a signed Frappe webhook on publish
  • A committed case-study seed as the fallback for builds and outages
  • Standalone Docker image behind nginx with HTTP/2 on our own server

Performance

Core Web Vitals: what moved our own score from 58 to 94

At launch, Lighthouse's mobile test scored our home page 58, with a simulated Largest Contentful Paint of 9.4 seconds. The page was not slow for real visitors, but the simulation charged every byte requested before first paint to the hero text — and the same pattern holds back real users on slow connections.

Four changes took it to 94 and the LCP to 2.8 seconds, with desktop at 100: HTTP/2 on the server; web fonts subset to the characters the site actually uses, cutting them from about 460 KB to 130 KB; analytics loaded when the browser is idle instead of in the document head, with page views still recorded; and carousel images given real sizes and no longer preloaded. None of it required a redesign. We run the same audit on client sites, and set budgets in CI so the score does not quietly drift back.

Technical SEO

SEO that the build generates, not a checklist someone maintains

Every page on this site gets its canonical URL, title and description from Next.js's metadata API, and its structured data — Service, FAQPage and BreadcrumbList on service pages, Article on blog posts — from the same data that renders the visible page, so the two cannot disagree. The sitemap, the RSS feed and the Open Graph image for each blog post are generated from the content in Frappe, and new or changed URLs are submitted to search engines through IndexNow.

After we replaced the previous site, the 24 old URLs that Google still had indexed were redirected with permanent 301s to their closest new page, and case studies we retired were redirected rather than left to return 404s. The redirect list lives in the Next.js config, versioned with the code.

Headless Liferay

Next.js as the public front end for Liferay DXP

Organisations on Liferay DXP often want a public site that is faster and easier to evolve than the portal, without moving content, workflow and permissions out of Liferay. In a headless setup, Liferay keeps authoring, approval workflow, translation and personalisation rules, and Next.js renders the public pages from its headless delivery APIs or GraphQL — statically where content is stable, on demand where it changes, with Liferay's publish events triggering revalidation the same way Frappe does on our site.

We have built the Liferay side of this for clients: for CIGNEX Datamatics, an API-first Liferay content platform delivering to three new digital channels in 12 language variants, with automated workflows that cut publishing time by 65 %. How the APIs, authentication and caching are designed is covered on our Liferay headless integration page.

Frappe and ERPNext

A Next.js front end for ERPNext and Frappe

ERPNext and Frappe ship with a built-in website and portal, which is enough for many internal and partner-facing needs. When the website has to rank, carry a brand, or combine ERP data with marketing content, a Next.js front end on Frappe's REST API is the pattern we use ourselves: product and service catalogues, customer portals showing orders and invoices, enquiry and registration forms that create records in the ERP, and content authored in the Frappe desk.

The rules are the ones our own site follows. API keys stay on the server and are never sent to the browser; customers sign in against Frappe's users and permissions rather than a second user store; reads are cached and purged by webhook; and writes go through whitelisted methods with server-side validation, so the ERP remains the single source of truth. The Frappe apps and doctypes behind such a front end are built by our custom Frappe app team.

Hosting, upgrades & cost

Where it runs, how it is upgraded and how it is priced

Vercel is the easiest place to run Next.js and a sensible default for many teams. When data residency, cost at scale or an existing estate argues otherwise, Next.js runs as a standalone Node server in a container — as this site does — on AWS, Azure, Google Cloud or your own servers, behind nginx or a CDN. We set up the pipeline either way, with preview deployments for content and code changes.

Older Next.js sites on the Pages Router keep working, and both routers can live in one application, so we move them to the App Router route by route rather than in a single rewrite. Projects start with a short, fixed-fee discovery — pages and templates, content sources, rendering strategy per route, integrations, languages, and the URLs and rankings that must survive — and end in an architecture and a fixed price for the first release.

Planning a new site or a headless front end?

A short, fixed-fee discovery gives you a rendering plan, a content model and a fixed price for the first release — and a straight answer on whether Next.js is the right choice.

Book a Next.js discovery

Our technology stack

What our Next.js sites run on

Next.js and React in TypeScript, reading content and data from Liferay DXP, Frappe and ERPNext, Spring Boot or Node.js APIs and GraphQL, deployed as a container behind nginx or on Vercel and AWS.

Next.js logoNext.jsReact logoReactNode.js logoNode.jsGraphQL logoGraphQLLiferay DXP logoLiferay DXPFrappe / ERPNext logoFrappe / ERPNextSpring Boot logoSpring BootPostgreSQL logoPostgreSQLDocker logoDockerNGINX logoNGINXGitHub Actions logoGitHub ActionsAWS logoAWS

How we deliver

From discovery to a Next.js site your team can run

Five phases, each ending in something you can check: a rendering plan, a content model wired to your CMS, working pages, a measured performance and SEO pass, and a launch that keeps your existing rankings.

STEP 01

Discover

Pages, templates, content sources and integrations mapped; rendering strategy chosen per route; a fixed price for the first release.

STEP 02

Content model

The CMS or ERP side set up or extended, API clients typed, caching and webhook revalidation wired before the first page is built.

STEP 03

Build in sprints

Pages and components delivered against real content in two-week sprints, with preview deployments your editors can review.

STEP 04

Performance & SEO

Lighthouse and Core Web Vitals budgets in CI, structured data validated, sitemap and redirects checked against the old site.

STEP 05

Launch & hand over

301s for every indexed URL, Search Console and IndexNow submissions, monitoring, documentation and pairing with your team.

FAQs

Next.js development — questions we are asked first

Should we use Next.js or plain React?+

Use Next.js when pages must be fast and indexable before anyone signs in — public sites, content, catalogues, landing pages. Use plain React on a Vite build for applications that live entirely behind a login. Many products use both: Next.js for the public site and the signed-in areas that benefit from server rendering, plain React for internal tools.

Do we have to host Next.js on Vercel?+

No. Vercel is convenient, but Next.js also runs as a standalone Node server in a Docker container on AWS, Azure, Google Cloud or your own servers. atsglobal.in runs that way, behind nginx on our own server.

Can Next.js be the front end for Liferay DXP?+

Yes. Liferay keeps authoring, workflow, translation and permissions, and Next.js renders the public pages from Liferay's headless REST or GraphQL APIs, revalidating when content is published. Where the portal itself should stay, React inside Liferay is often the better option.

Can Next.js be the website for ERPNext or Frappe?+

Yes — our own site reads its blog and case studies from Frappe this way, with API keys kept on the server and a webhook refreshing the cached pages whenever a record is saved. For customer portals, users sign in against Frappe's own users and permissions, so there is no second user store to keep in step.

Will our editors need a developer to publish?+

No. Editors keep working in the CMS or ERP. A publish triggers a webhook that purges the cached pages, so the change is live on the next request, and the sitemap and feed update with it.

Can you migrate our Pages Router, Create React App or Gatsby site?+

Yes, incrementally. The Pages Router and the App Router can run side by side in one application, so routes move one at a time; for Create React App and Gatsby we rebuild on the App Router while keeping every URL or redirecting it, so rankings carry over.

Let’s work together

Tell us what the site has to do

Send a short description of the site, where its content lives and what it has to connect to — we will come back within a couple of days with a view on the approach and a bracket, and a fixed price after discovery.