TLDlive

How to Detect Next.js and React on a Website

React is a UI library and Next.js is a framework built on it, so the signs overlap but are not the same. This guide separates them, lists the markers for the Pages Router and the App Router, and explains why detection is less certain than for a CMS.

React is a library, Next.js is a framework

React renders user interfaces from components. It does not decide how pages are routed, how data is fetched on the server or how the code is bundled. Next.js, made by Vercel, adds those decisions: file-based routing, server-side rendering, static generation, API routes and an optimised build. A site built with Next.js is also a React site. A React site is not necessarily Next.js; it might be a single-page app made with Vite or Create React App, a Remix or Gatsby site, or a plain React widget embedded in an otherwise ordinary page.

For detection this means you work from the specific to the general: look for framework markers first, then for React itself.

Next.js markers in the HTML

  • Script and style paths under /_next/. Build output is served from /_next/static/, for example chunks in /_next/static/chunks/. Optimised images are requested from /_next/image?url=.... This is the strongest single marker, and it survives most customisations because the framework expects it. A configurable assetPrefix can move static files to a CDN host, but the /_next/static/ segment usually remains in the path.
  • A root element with the id __next. Pages Router applications mount into this element.
  • A script id="__NEXT_DATA__" type="application/json" element. The Pages Router serialises page props there so that the browser can hydrate. Reading it shows the page route, build ID and props. Be aware that it can contain whatever data the page used, so look at it only for the structure, not the content.
  • The App Router. Newer applications that use the App Router do not use __NEXT_DATA__. Instead they embed React Server Components payload chunks through inline scripts calling self.__next_f.push, and still serve assets from /_next/static/.
  • Meta tag. Some Next.js pages include <meta name="next-head-count">, a marker of older Pages Router versions.

Next.js markers in headers and behaviour

  • X-Powered-By: Next.js is added by default in self-hosted setups. Many deployments disable it via the poweredByHeader option, and Vercel hosting adds its own headers such as x-vercel-id.
  • A response header x-nextjs-cache may report HIT or MISS for statically generated pages in some versions.
  • Prefetch requests: in DevTools, navigating between pages loads small JSON or RSC responses on hover or on link visibility, rather than full documents. This indicates client-side routing in a React framework.

React markers

SignalMeaningReliability
data-reactroot attributeServer-rendered React before version 18High for older sites; React 18 and later no longer add it
__REACT_DEVTOOLS_GLOBAL_HOOK__ on windowPresent when the React DevTools extension is installed, even on non-React pagesNot a site signal; ignore it
Elements with keys starting __reactFiber$ or __reactProps$React attached internal data to DOM nodes (readable in the console)High, but only with JavaScript access
Bundle file names such as react-dom or a main.*.js built by a React toolchainReact bundles; names varyMedium
A near-empty body with a single div id="root"Client-side rendered single-page appMedium; also true of other frameworks

The framework test is easier in a browser than in a raw HTTP fetch, because React's internal markers are attached when the code runs. A crawler that only fetches HTML sees the server-rendered markup and the script tags, which is why server-rendered Next.js is detected so reliably by path while client-only React apps are harder.

Other frameworks that look similar

Do not assume that every modern site is Next.js. Nuxt, the Vue equivalent, uses /_nuxt/ and a __NUXT__ global. Gatsby uses a ___gatsby root. Remix and React Router use their own hydration data scripts. SvelteKit uses /_app/immutable/ paths. Astro emits astro-island custom elements. A quick glance at the asset path prefix usually distinguishes them. Pair that with the CMS checks in what CMS a website uses, because a decoupled site may run Next.js in front of WordPress, a hosted headless CMS or a commerce API.

Detecting the host

Next.js is often hosted on Vercel, but also on Netlify, Cloudflare, AWS or ordinary servers. Header hints like x-vercel-id identify the host, while the edge may be a general CDN, as discussed in Cloudflare and CDN detection. Separating framework, host and CDN gives a correct stack description: for instance "Next.js on Vercel, behind its own edge network".

Why it matters

  • Developer hiring and agency targeting. The framework tells you which skills a site's maintainers need.
  • Technical SEO. Server-rendered and static pages are easy for crawlers; client-only apps can need extra care for indexing.
  • Security triage. Framework version matters when a vulnerability is announced. A detector with version patterns, such as the ones in Lens's catalogue, can help to find which sites might be affected, but hardened sites often hide versions.
  • Market research. Whether new sites choose a JavaScript framework or a hosted builder is a recurring question, which the live data on /technologies helps to answer for the sites observed.

A console recipe

  1. Open DevTools, then the Elements tab, and search for __next and _next/static.
  2. In the console, run !!document.getElementById('__NEXT_DATA__') for the Pages Router, and typeof self.__next_f for the App Router.
  3. Check the response headers for x-powered-by and x-vercel-id.
  4. If none of this matches, look for other framework prefixes before deciding it is custom React.

The TLDlive Lens catalogue performs the equivalent checks on every page you visit and lists React, Next.js and related tooling in the popup. See technology fingerprinting and privacy for how that happens without collecting page content.

Sources

Frequently asked questions

How do I check if a website uses Next.js?

Look in the page source for requests to /_next/static/ and a __next root or a __NEXT_DATA__ script. Pages built with the App Router use self.__next_f instead of __NEXT_DATA__ but still load assets from /_next/static/.

Does Next.js always send an X-Powered-By header?

By default self-hosted Next.js sends X-Powered-By: Next.js, but the setting can be turned off and some hosts remove or override headers, so absence proves nothing.

Can I tell the React version?

Sometimes. Bundle comments, a global version string or a detector's version pattern can reveal it, but production builds often hide it. Treat an unknown version as normal.

Is every site with /_next/ in its URLs hosted on Vercel?

No. Next.js can be hosted anywhere that runs Node.js or a compatible edge runtime. Hosting is determined by headers and DNS, not by the framework markers.