Skip to content

Instantly share code, notes, and snippets.

@timruffles
Last active February 23, 2024 17:04
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save timruffles/153a04f6956399907d90d73af0093e9f to your computer and use it in GitHub Desktop.
Save timruffles/153a04f6956399907d90d73af0093e9f to your computer and use it in GitHub Desktop.
Next.js page request handling

How Next.js responds to a page request with HTML

We create the next request handler function via app.getRequestHandler(). This returns a standard express handler, so we use it like expressApp.get('*', middlewareA(), middlewareB(), nextApp.getRequestHandler()).

When the handler is invoked:

  • Server#handleRequest (next-server/server/lib/next-server.js)
    • Parses URL + query string if not already done
  • Server#run
    • Searches for matching route
      • Runs it
        • The routes were generated in #generateRoutes
      • Or 404
    • Some crazy stuff - lots of router layers, eventually gets to #render
  • Server#render
    • Checks if it’s an internal page, or blocked, and returns
  • Server#renderToHTML
    • In dev, will trigger a rebuild
      • This fires complete callbacks per page, so we respond as soon as our page is ready, not all pages
      • Will output manifest too which lists what we’re outputting
    • In production we have prebuilt everything
    • App/document code is loaded via standard cjs require()
      • So it’s just running in Node, nice n simple
        • And cached in production etc
      • Loading page is via require, path generated by next-server/server/require.js
        • Again pointing to a output file in .next build, .next/server/static/development/pages/some-page.js
      • Webpack has output it as CJS
        • e.g .next/server/static/development/pages/_document.js
    • Then we generates the HTML required to load the page
      • Passed lists of all scripts required, take from the manifest file
      • Calls Document.getInitialProps to get initial data used in our SSR
      • Then creates our { type: Document, … } vdom value
      • Our vdom tree is passed to renderToStaticMarkup, which will instantiate our components, call render, and output a string HTML
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment