FRootLayout → HTML + Flight
Next.js App Router/initial page response/first principles

Your layout.js becomes two coordinated outputs

A pipeline: your layout.js source becomes a server-rendered React tree, then HTML, then a Flight payload, then browser hydration / reconciliation. The anchor throughout is your exact output, not a generic example.

2coordinated outputs
1HTTP response
0 KBserver components ship
10mental models
The most important early correction

Your layout is converted into plain HTML and forgotten. Next produces two coordinated outputs: visible HTML for the first paint, and an embedded React / Flight model so the browser knows what React tree that HTML represents.

Your pasted source/output is the classic Next App Router initial page response: the visible HTML is only one half of the result; the many self.__next_f.push(...) scripts are the embedded React Server Components / Flight payload that lets the browser reconstruct the React tree behind that HTML.

▸AT FIRST PRINCIPLES LEVEL

One source, two outputs, one response

At first principles level, your app/layout.js is compiled, called as a Server Component, and its returned React element tree is rendered into two things that ship in a single HTML response.

app/layout.js → server module → Server Component → React tree → ( HTML + Flight )
sourceapp/layout.js
compiledserver module
invoked asa Server Component
returnsa React element tree
Next / React render that tree into:
output 1HTMLfor immediate display
output 2RSC / Flight payloadfor React + router state
deliverybrowser receives bothin one HTML response
1SERVER COMPONENT, NOT A TEMPLATE

Your RootLayout is not an HTML template

app/layout.js — what you wrote
function RootLayout({ children }) {
  console.log('layout rendered')

  return (
    <html lang="en">
      <body>
        {children}

        <footer>
          <p>Page rendered on {new Date().toLocaleString()}</p>
        </footer>
      </body>
    </html>
  )
}

This does not mean: “Next copies this JSX into an HTML file.” It means: “Next will call this function during rendering, and the return value becomes part of a React tree.”

In the App Router, app/layout.js is a special file. The top-most one is the root layout, and it must define the document-level <html> and <body> tags. Because you did not put "use client" at the top, this layout is a Server Component by default — layouts and pages render on the server, can be streamed, and only need Client Components when you require browser APIs, event handlers, state, effects, and so on.

this lineconsole.log('layout rendered')logs in the server terminal, not the browser console.
this linenew Date().toLocaleString()runs during the server render.

In your pasted HTML, that is why the final page contains:

final page output
Page rendered on <!-- -->6/22/2026, 9:53:29 PM

The <!-- --> is a React server-rendering text separator. It helps React preserve exact text-node boundaries when reconciling the server-rendered DOM.

2FILESYSTEM → ROUTE TREE

Next first builds a route tree from your filesystem

Your files roughly imply this route tree. Next reads the folder structure as routing information.

files on disk
src/app
├─ layout.js      ← RootLayout
├─ styles.css     ← imported by RootLayout
└─ page.js        ← Home page for /
read as routing information
URL /
└─ root segment ""
   ├─ layout: RootLayout
   └─ page: Home

So your final React tree is not just RootLayout. It is closer to:

nested with the router slot
RootLayout
└─ children slot
   └─ LayoutRouter
      └─ Home page

That is why your output contains internal references like the following — these are not components you wrote. They are App Router infrastructure that Next inserts around your route so it can support nested layouts, templates, loading states, errors, not-found pages, metadata, streaming, and client-side navigation.

infrastructure Next inserts
layout-router.js
render-from-template-context.js
error-boundary.js
not-found-boundary.js
metadata-boundary.js
3{children} → THE RENDERED PAGE

Your {children} becomes the rendered page

Your layout says <body> {children} <footer>...</footer> </body>, and your page likely returns something like <main><h1>Hello Next!</h1></main>. So the render tree becomes:

render tree
<html lang="en">
└─ <body>
   ├─ <main>
   │  └─ <h1>Hello Next!</h1>
   └─ <footer>
      └─ <p>Page rendered on 6/22/2026, 9:53:29 PM</p>

Which is exactly why the visible HTML becomes:

visible HTML
<body>
  <main>
    <h1>Hello Next!</h1>
  </main>

  <footer>
    <p>
      Page rendered on
      <!-- -->6/22/2026, 9:53:29 PM
    </p>
  </footer>

  ...
</body>

So the direct transformation is:

RootLayout({ children }) → rendered HTML
RootLayout({ children: <Home /> })
      ↓
<html>
  <body>
    <Home />
    <footer />
  </body>
</html>
      ↓
<html>
  <body>
    <main><h1>Hello Next!</h1></main>
    <footer>...</footer>
  </body>
</html>
4THE METADATA SYSTEM

Why did Next add <head> if you did not write one?

Your source only wrote <html lang="en"><body>...</body></html>. But your output has a head you never authored:

emitted <head>
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  ...
</head>

That comes from Next’s document/metadata system. In the App Router, metadata is resolved on the server so it can be included in the initial HTML response. Even when you do not explicitly export custom metadata, Next still emits essential defaults like charset and viewport. The metadata system is why your Flight payload includes entries such as:

metadata entries in the Flight payload
MetadataBoundary
ViewportBoundary
__next_metadata_boundary__
__next_viewport_boundary__

So mentally — your layout is wrapped by Next’s full document shell:

your layout vs the Next document shell
Your layout:
<html>
  <body>...</body>
</html>

Next document shell:
<!doctype html>
<html>
  <head>
    metadata
    CSS links
    preload hints
    framework scripts
  </head>
  <body>
    rendered app
    Flight payload
  </body>
</html>
5GLOBAL CSS → <link>

Why did your CSS import become a <link> tag?

You wrote import "./styles.css"; Next sees that import in the root layout and treats it as a global app-level stylesheet — global CSS can be imported from the root layout to apply styles across routes.

source import
import "./styles.css";
in the HTML response
<link
  rel="stylesheet"
  href="/_next/static/css/app/layout.css?v=1782158009762"
  data-precedence="next_static/css/app/layout.css"
/>

That means:

bundled, extracted, linked
styles.css
  ↓ bundled/extracted by Next
/_next/static/css/app/layout.css
  ↓ linked in <head>
browser downloads CSS as a normal stylesheet

The ?v=1782158009762 part is a development-mode cache-busting timestamp. It helps the browser get the newest stylesheet during dev.

6THE CLIENT RUNTIME

Why are there framework scripts?

Your output has the following — these are not from your layout. They are the Next / React client runtime.

scripts in the response
<link rel="preload" as="script" href="/_next/static/chunks/webpack.js?v=..." />

<script src="/_next/static/chunks/main-app.js?v=..." async=""></script>
<script src="/_next/static/chunks/app-pages-internals.js" async=""></script>
<script src="/_next/static/chunks/polyfills.js" nomodule=""></script>
roughly
webpack.js
  module loader/runtime in dev

main-app.js
  App Router client bootstrap

app-pages-internals.js
  internal client components used by the router:
  LayoutRouter, ErrorBoundary, NotFoundBoundary, etc.

polyfills.js
  fallback support for older browsers

Even though your own RootLayout is a Server Component, the browser still needs some JavaScript so Next can hydrate Client Components, manage the App Router, process future navigations, and interpret the embedded RSC payload.

7THE BIG ONE

What are self.__next_f.push(...) scripts?

These are the embedded React Server Components payload, often called the Flight payload.

On the server, Server Components render into a special RSC payload, and that payload plus Client Component instructions are used to prerender HTML. On the first client load: HTML gives the immediate non-interactive preview, the RSC payload reconciles the Server and Client Component trees, and JavaScript hydrates Client Components.

So your response is not just HTML. It is:

the full response
HTML shell
+
RSC/Flight payload
+
router bootstrap data
+
client runtime scripts
HTML answers:

“What should the browser paint immediately?”

Flight payload answers:

“What React tree produced this HTML, and how should the App Router continue from here?”

That is why you see this — it initializes the client-side Flight buffer:

buffer init
<script>
  (self.__next_f = self.__next_f || []).push([0]);
</script>

Then you see many chunks like this — they stream pieces of the rendered React model into the browser:

streamed chunks
<script>
  self.__next_f.push([1, '...serialized React model...']);
</script>

On initial load the component payload arrives embedded in the HTML stream; later navigations can fetch only the RSC payload without a full HTML document.

8DECODING THE PAYLOAD

Decoding the important parts of your Flight payload

8: — a Server Component was rendered
8:{"name":"RootLayout","env":"Server", ...}

means React recorded that a Server Component named RootLayout was rendered.

5: — serialized React element model for your layout
5:["$","html",null,{
  "lang":"en",
  "children":["$","body",null,{...}]
}]

In human terms:

5:
  React element:
    type: "html"
    props:
      lang: "en"
      children:
        React element:
          type: "body"
          children:
            - LayoutRouter / children slot
            - footer
c: — your page rendered on the server
c:{"name":"Home","env":"Server", ...}

means your Home page component was also rendered on the server.

b: — your page output
b:["$","main",null,{
  "children":["$","h1",null,{"children":"Hello Next!"}]
}]

is your page output:

<main>
  <h1>Hello Next!</h1>
</main>
6: — an importable client module
6:I["...layout-router.js",["app-pages-internals","static/chunks/app-pages-internals.js"],""]

means:

ID 6 refers to an importable client module:
Next's LayoutRouter
found in app-pages-internals.js
3: — a resource hint for your CSS
3:HL["/_next/static/css/app/layout.css?v=1782158009762","style"]

is a resource hint / preload-style instruction for your layout CSS.

1c: / 1a: — the metadata
1c:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}]]
1a:[["$","meta","0",{"charSet":"utf-8"}]]

corresponds to the metadata that eventually appears in the <head>:

<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />

The exact wire tokens like I, HL, D, $L6, $Y, $E(...) are React/Next implementation details, not public API. But conceptually they mean:

I
import/module reference
HL
preload/link/resource hint
$
React element encoding
$L6
reference to another record/module by ID
$E
encoded server-side function reference / special value
$Y
placeholder/internal unresolved or opaque value

Do not build application logic around those exact tokens. They can change between React/Next versions.

9THE MACHINERY

Why does the payload include things you did not write?

You see things like the following — because your app is not rendered as only RootLayout → Page. It is rendered inside Next’s App Router machinery.

boundaries & roots you never authored
NotFoundBoundary
OutletBoundary
MetadataBoundary
ViewportBoundary
GlobalError
ClientPageRoot
ClientSegmentRoot
App Router request for /
App Router request for /
└─ Root layout
   └─ Router slot: children
      ├─ error boundary
      ├─ not-found boundary
      ├─ metadata boundary
      ├─ viewport boundary
      ├─ template context
      └─ page segment

So your real server render is closer to this. You only authored the clean part; Next wraps it in the machinery required to make nested routing, streaming, errors, metadata, prefetching, and client navigation work.

the real server render
<Request />
  ↓
<AppRouterServerRender>
  ↓
<RootLayout>
  <body>
    <LayoutRouter parallelRouterKey="children">
      <TemplateContext>
        <ErrorBoundary>
          <NotFoundBoundary>
            <MetadataBoundary>
              <Home />
            </MetadataBoundary>
          </NotFoundBoundary>
        </ErrorBoundary>
      </TemplateContext>
    </LayoutRouter>

    <footer />
  </body>
</RootLayout>
you only authored the clean part
RootLayout
Home
styles.css
10THE FULL TIMELINE

The full request timeline

browser request / → server render → streamed response → paint → hydrate → navigate
1Browser requests /
2Next dev server receives request
3App Router matches / to: app/layout.js + app/page.js
4Server module graph is loaded
5RootLayout is called on the server
6Home page is called on the server
7React produces RSC / Flight model
8Next uses that model to produce HTML
9Response streams to browser — doctype, html/head/body, visible page HTML, CSS links, runtime scripts, self.__next_f.push(...) chunks
10Browser parses HTML immediately
11User sees: Hello Next! · Page rendered on ...
12Next client runtime loads
13Runtime reads self.__next_f buffer
14React reconciles the RSC payload with the existing DOM
15Client Components, if any, hydrate
16Future navigation can use RSC payloads instead of full HTML reloads
11THE SHORTEST ACCURATE EXPLANATION

The shortest accurate explanation

Your RootLayout becomes the final HTML because Next calls it as a Server Component and turns its returned React element tree into server-rendered markup. But Next also embeds the Flight/RSC payload because HTML alone is not enough for the App Router — the browser also needs the serialized React tree, router state, module references, metadata boundaries, and Client Component references so React can reconcile the page and Next can perform client-side navigation.

So this:

this
<html lang="en">
  <body>
    {children}
    <footer>...</footer>
  </body>
</html>

becomes two things:

Visible HTML
<html>
  <body>
    <main>Hello Next!</main>
    <footer>Page rendered on ...</footer>
  </body>
</html>
React/Next continuation data
self.__next_f.push(...)
self.__next_f.push(...)
self.__next_f.push(...)
lock this inThe HTML is what the browser paints.
lock this inThe Flight payload is what React/Next uses to remember, resume, reconcile, and navigate the app.
▾ZOOM ALL THE WAY DOWN

self.__next_f.push(...) — what is each part?

That line is ordinary browser JavaScript first, and only then a Next.js-specific convention. The confusing part is that Next hides a streaming protocol inside something that looks like a normal array operation.

just JavaScript running in the browser
<script>
  (self.__next_f = self.__next_f || []).push([0]);
</script>
break it into three parts
self . __next_f . push(...)
self
the browser global object
__next_f
a Next.js-created global property
push(...)
append something into that array/queue

1 · What is self?

In a browser page, self is a reference to the global browser object. In normal page JavaScript:

self === window       // true
self === globalThis   // true, in the browser main thread

So these are basically equivalent in this context:

self.__next_f
window.__next_f
globalThis.__next_f

Think of self as the top-level browser world where page-wide globals live. So self.__next_f means window.__next_f — in plain English: “Store this thing on the global browser object so different scripts can access it.”

2 · What is __next_f?

__next_f is not a JavaScript built-in. It is a custom global property created by Next.js. The name roughly means:

__next_f
│      │
│      └─ probably "Flight"
└──────── internal Next.js thing

React Server Components use a transport format often called Flight. Next embeds chunks of that Flight payload into the HTML using this global array. So self.__next_f means the place where Next stores incoming Flight/RSC chunks. A simplified mental model — it is basically a mailbox:

a mailbox
self.__next_f = [
  [0],
  [1, "some serialized React Server Component data"],
  [1, "more serialized React Server Component data"],
  [1, "more serialized React Server Component data"]
]
the server sends little messages into the page
Server
  ↓
<script>self.__next_f.push(...)</script>
  ↓
Browser global queue
  ↓
Next client runtime reads the queue
  ↓
React reconstructs/reconciles the app tree

3 · What is push?

push is the normal JavaScript array method. Example:

const messages = []

messages.push("hello")
messages.push("world")

console.log(messages)
// → ["hello", "world"]

So self.__next_f.push([1, "some payload"]) means append this Flight chunk to the __next_f array. In ordinary JavaScript terms, self.__next_f.push([0]) adds the item [0] to the end of the array self.__next_f.

4 · Read the whole expression slowly

This line does two jobs: (1) make sure self.__next_f exists, and (2) push the first chunk into it.

compact
(self.__next_f = self.__next_f || []).push([0]);
expanded
if (!self.__next_f) {
  self.__next_f = []
}

self.__next_f.push([0])

The parentheses matter: (self.__next_f = self.__next_f || []) returns the array; then .push([0]) pushes into that array. In words: “Use the existing Next Flight array if it already exists. If it does not exist, create an empty array. Then push [0] into it.”

5 · Why not just const __next_f = []?

Because each inline <script> tag is separate. Your HTML has many chunks like this — and each script needs access to the same shared place:

separate scripts, one shared queue
<script>
  (self.__next_f = self.__next_f || []).push([0]);
</script>

<script>
  self.__next_f.push([1, "...first Flight chunk..."]);
</script>

<script>
  self.__next_f.push([1, "...second Flight chunk..."]);
</script>

<script>
  self.__next_f.push([1, "...third Flight chunk..."]);
</script>

So Next puts the shared place on the global object. That way, every script tag can say self.__next_f.push(...) and they are all pushing into the same queue.

the global object
window / self
└─ __next_f
   ├─ chunk 0
   ├─ chunk 1
   ├─ chunk 2
   └─ chunk 3

6 · Why does Next do this?

Because the HTML response is streamed. The browser can start receiving and parsing the page before the whole response is complete. So Next can send the page in pieces, and the inline scripts act like little delivery packets:

Next can send
HTML shell
↓
visible page markup
↓
Flight chunk
↓
more HTML
↓
Flight chunk
↓
more Flight chunks
browser receives it like this
Incoming HTML stream
        │
        ▼
Browser parser
        │
        ├─ sees <main><h1>Hello Next!</h1></main>
        │      ↓
        │    paints visible page
        │
        ├─ sees <script>self.__next_f.push(...)</script>
        │      ↓
        │    executes script immediately
        │      ↓
        │    stores Flight chunk in __next_f
        │
        └─ continues parsing

As soon as the browser reaches one, it runs it and stores the chunk. So the browser does not need to wait for one giant JSON file at the end.

7 · The important subtlety

At first, self.__next_f behaves like a normal array. But when Next’s client runtime loads, it reads that array. Conceptually:

for (const chunk of self.__next_f) {
  processFlightChunk(chunk)
}

Then Next can continue processing later chunks as they arrive. So the real mental model is:

before runtime is ready

__next_f is a buffer.

after runtime is ready

__next_f becomes a delivery channel.

Meaning: early chunks are stored, later chunks are consumed/processed.

8 · The whole thing in one diagram

server render → HTML + Flight chunks → browser parses script → global queue → runtime → reconcile
serverServer renders your app
producesHTML + Flight chunks
sendsHTML response to browser
browser parses(self.__next_f = self.__next_f || []).push([0])
window / self → __next_f
▸[0]
▸[1, "...serialized React tree..."]
▸[1, "...more serialized React tree..."]
consumesNext client runtime reads __next_f
react understandswhat Server Components rendered · where Client Components are · what router state exists · how to reconcile with the existing HTML
selfthe browser global object
__next_fNext's Flight data queue
pushadd this chunk to the queue
◆A DIAGRAM MODEL OF ALL THIS

Ten models of self.__next_f.push(...)

In your HTML, Next uses this pattern many times to stream React/Flight chunks into the browser. Here it is from ten angles.

1 · The smallest model

self.__next_f.push(chunk)
│    │        │
│    │        └─ put this item at the end of the queue
│    │
│    └────────── Next.js Flight queue
│
└─────────────── browser global object

In plain English: “On the browser's global object, find Next's Flight queue, then append this new Flight chunk.”

2 · Browser global object model

In the browser, self === window. So self.__next_f is basically window.__next_f.

Browser tab
└─ Global object
   ├─ window
   ├─ self
   ├─ document
   ├─ location
   ├─ console
   └─ __next_f   ← Next adds this

So self is not special to Next — self is the browser-wide object. __next_f is the special Next.js part.

3 · What __next_f looks like

first Next creates this
self.__next_f = []
then keeps adding chunks
self.__next_f.push([0])
self.__next_f.push([1, "...Flight data..."])
self.__next_f.push([1, "...more Flight data..."])
mentally
self / window
└─ __next_f
   ├─ [0]
   ├─ [1, "RootLayout model..."]
   ├─ [1, "Home page model..."]
   ├─ [1, "metadata model..."]
   └─ [1, "router state..."]

__next_f is a global queue.

4 · Why the first line is written strangely

does it already exist?
Does self.__next_f already exist?
        │
        ├─ No
        │   ↓
        │  create []
        │
        └─ Yes
            ↓
           reuse it

Then:
  push [0] into it

So this line is an initialization + first push: create the mailbox if needed, then drop the first message into it.

5 · Response streaming model

the server streams the response
Next server
   │
   ├─ sends document shell
   │
   ├─ sends visible HTML
   │
   ├─ sends script: self.__next_f.push(...)
   │
   ├─ sends more HTML
   │
   ├─ sends another script: self.__next_f.push(...)
   │
   └─ sends more Flight chunks
browser receives it
Incoming HTML stream
        │
        ▼
Browser parser
        │
        ├─ sees <main><h1>Hello Next!</h1></main>
        │      ↓
        │    paints visible page
        │
        ├─ sees <script>self.__next_f.push(...)</script>
        │      ↓
        │    executes script immediately
        │      ↓
        │    stores Flight chunk in __next_f
        │
        └─ continues parsing

6 · Full model: HTML + Flight together

Your page response has two coordinated layers:

Layer 1: HTML

What the browser paints immediately

Layer 2: Flight payload

What React/Next uses to understand the app tree

more detailed
Next server renders:
  RootLayout + Page
        │
        ▼
Produces two outputs
        │
        ├─────────────────────────────┐
        ▼                             ▼
Visible HTML                    Flight / RSC data
for the browser                 for React/Next
        │                             │
        ▼                             ▼
<main>Hello Next!</main>        self.__next_f.push(...)
<footer>...</footer>            self.__next_f.push(...)
        │                             │
        └──────────────┬──────────────┘
                       ▼
              Same HTTP response
                       ▼
                  Browser receives

7 · The mailbox model

this is the easiest model
self.__next_f is a mailbox.

Server keeps inserting letters:

  letter 1: "start Flight stream"
  letter 2: "RootLayout rendered like this"
  letter 3: "Home rendered like this"
  letter 4: "CSS resource is here"
  letter 5: "metadata is this"
  letter 6: "router state is this"

Next client runtime later opens the mailbox
and reads the letters.
Server
  │
  │ writes chunks into inline scripts
  ▼
<script>self.__next_f.push(chunk)</script>
  │
  │ browser executes scripts
  ▼
window / self
└─ __next_f
   ├─ chunk
   ├─ chunk
   ├─ chunk
   └─ chunk
        │
        │ Next client runtime reads these
        ▼
React / Next app state

8 · Timeline model

1Browser asks for /
2Next renders RootLayout on the server
3Next renders page inside {children}
4Next produces HTML
5Next produces Flight chunks
6Browser receives HTML
7Browser paints visible content
8Browser runs inline scripts
9self.__next_f receives chunks
10Next client runtime loads
11Runtime reads __next_f
12React reconciles with the existing HTML

9 · Runtime ownership model

before the runtime is ready
self.__next_f
└─ behaves like a normal array buffer
   ├─ push chunk
   ├─ push chunk
   └─ push chunk
after the runtime is ready
Next runtime
└─ reads self.__next_f
   ├─ process old chunks
   ├─ listen for new chunks
   └─ connect Flight data to React

Phase 1: buffer

“Store chunks until Next is ready.”

Phase 2: transport channel

“Deliver chunks to the Next runtime.”

10 · Final lock-in model

the master schematic
Next serverRootLayout + Page render
two outputs
Visible HTML<main>...</main>
<footer>...</footer>
Flight payloadReact tree data
router state
module refs
transportBrowser stream
Browser global objself / window  └─ __next_f []
push(...)
__next_f queue
▸[0]
▸[1, "..."]
▸[1, "..."]
consumerNext client runtime
resultReact reconciles
with existing HTML
selfthe browser-wide object
__next_fNext's global Flight chunk queue
pushappend this new chunk into that queue

HTML gives the browser something to paint. __next_f gives React/Next the serialized app model needed to continue, reconcile, hydrate, and navigate.

Back to JIT-Atlas