Skip to main content

Sitecore

Exploring Next.js Conf by Vercel: New Features in Version 15 and Their Significance

Next.Js Vercel Conference

Img 20241024 180252 1 I’ve been working with Next.Js for a quite a while and have been watching its development with interest all this time. Last week I was happy attended Next.js Conf in San Francisco. Perficient was proud to sponsor the event, allowing us to showcase our Sitecore Practice alongside my colleague David Lewis from the Optimizely Practice.

Vercel released new version 15 of Next.js framework. That was truly innovative day and I’d like to share my takeaways from the event about this new version.

Vercel seriously worked on mistakes

In the past, the Next.js team made some questionable decisions, such as rushing releases and maintaining rigid opinions despite community feedback. This included changes like rewriting the fetch API, implementing hard caching, and introducing numerous bugs, among other issues, while once again overlooking community requests. It took nearly a year for the team to recognize that these approaches were ineffective and to begin addressing the underlying problems. With the release of version 15, there is finally a sense that the framework is truly meeting the needs of its community, much as it has successfully done in previous iterations.

React 19

We are currently facing an unusual situation. Over six months have passed since the release candidate of React.js was introduced, yet the stable version has not been published. This delay directly impacts Next.js, as the two frameworks are closely intertwined. As a result, Next.js is currently utilizing the release candidate version of React.js, but this is only partially accurate. In reality, Next.js employs two different React.js configurations:

  • React.js 19 Canary for the App Router
  • React.js 18 for the Pages Router

Interestingly, there was an initial plan to integrate the React.js 19 version for the Pages Router as well. However, these changes were later rolled back. Full support for React.js version 19 is expected once the stable release is officially launched.

Form component

This next.js innovation is in fact already familiar form from react-dom, but with some improvements. You benefit from Next.Js implementation primarily in cases when a successful form submission involves a transition to another page. In that case, the loading.tsx and layout.tsx abstractions for the following page will get preloaded.

import Form from 'next/form'
 
export default function Page() {
  return (
    <Form action="/search">
      {/* On submission, the input value will be appended to 
          the URL, e.g. /search?query=abc */}
      <input name="query" />
      <button type="submit">Submit</button>
    </Form>
  )
}

Img 20241024 115119

Developer Experience (DX)

When discussing Next.js, the developer experience (DX) is impossible to overlook. Beyond the typical “Faster, Higher, Stronger” claims, Next.js has introduced several meaningful improvements that significantly enhance DX:

  1. Long-awaited support for ESlint v9. Next.js never supported ESlint v9. This is despite the fact that both eslint (v8) and some of its own dependencies were already marked as deprecated. Because of that developers were essentially forced to keep deprecated packages.
  2. The error interface in next.js – which is already clear and convenient – was slightly improved:
    1. Added a button to copy the call stack;
    2. Added the ability to open the source of the error in the editor on a specific line.
  3. Added Static Indicator – an element in the corner of the page showing that the page is built in static mode. The pre-built page indicator has been with us for years so it was slightly updated and adapted for App Router.
  4. Also added a directory with debug information – .next/diagnostics. That’s where one can find information about the build process and all errors that occur (sometimes helps to parse problems).

Versioning the documentation

One particularly valuable enhancement is the ability to access different versions of the documentation. But why is this so crucial for the developer experience?

Updating Next.js to accommodate major changes can be a challenging and time-consuming task. As a result, older versions like Next.js 12 and 13 remain widely used, with over 2 million and 4 million monthly downloads respectively. Developers working with these versions need documentation that is specific to their setup, as the latest documentation may include significant changes that are not compatible with their projects. By providing versioned documentation, Next.js ensures that developers have the reliable resources they need to maintain and update their applications

Turbopack

Probably the biggest news:

  • Turbopack is now fully complete for development mode! “100% of existing tests ran with no errors for Turbopack”
  • Now the turbo team is working on the production version, progressively going through the tests and covering them all (currently about 96%)

Turbopack introduces a range of new features that enhance its functionality and performance:

  1. Setting a memory limit for a Turbopack build;
  2. Tree Shaking (in other words that is removal of the unused code):
  3. const nextConfig = {
      experimental: {
        turbo: {
          treeShaking: true,
          memoryLimit: 1024 * 1024 * 512 // bytes (512MB)
        },
      },
    }

    These turbopack change alone reduced memory usage by 25-30% and speeded up heavy page assembly by 30-50%.”

  4. Fixed significant issues with styles. In version 14, there were often situations when the styles were broken in order during navigation, and because of this, style A became higher than style B, then lower. This changed their priority and, accordingly, the elements looked different.
  5. The next long-awaited improvement. Now you can write the configuration in TypeScript, and the file correspondingly would be next.config.ts:
    import type { NextConfig } from 'next';
     
    const nextConfig: NextConfig = {
      /* here goes you config */
    };
     
    export default nextConfig;

    Same strongly-typed syntax as usual, but very nice to have, finally!

  6. Another interesting innovation is retrying a failed page generation before actually failing the build for static pages. If the page fails the assembly for the connectivity issues, it will try it again:
    const nextConfig = {
      experimental: {
        staticGenerationRetryCount: 3,
      },
    }

Framework API changes

Updating Next.js often involves some of the most challenging aspects, and version 15 is no exception with its critical enhancements.

One significant change in version 15 is the transition of several framework APIs to asynchronous operations. This shift particularly affects the core framework-centric abstractions, including:

  • cookies,
  • headers,
  • params and
  • searchParams (also called Dynamic APIs).
import { cookies } from 'next/headers';
 
export async function AdminPanel() {
  const cookieStore = await cookies();
  const token = cookieStore.get('token');
  // ...
}

The changes are big indeed, but the Next.js team suggests one could update to the new APIs automatically by calling their codemod:

npx @next/codemod@canary next-async-request-api .

Caching

In my opinion, that is where the most important changes have happened. And the most important news is that Caching is now disabled by default!

Let’s take a look on what’s changed:

  • Actually, fetch now uses the no-store value by default instead of force-cache;
  • API routes use force-dynamic mode by default (previously it was force-static by default);
  • Caching in the client router has also been disabled. Previously, if a client visited a page within the path, it was cached on the client and remained in this state until the page reload. Now the current page will be loaded each time. This functionality can be altered via next.config.js:
    const nextConfig = {
      experimental: {
        staleTimes: {
          dynamic: 30 // defaults to 0
        },
      },
    }
  • Moreover, even if client caching is enabled, it most likely will be updated at the correct time. Namely, if the enabled page cache on the server expires.
  • Server components are now cached in development mode. Due to this, updates in development are faster.
  • Following the above, one can reset the cache by just reloading a page or can also completely disable the functionality via next.config.js:
    const nextConfig = {
      experimental: {
        serverComponentsHmrCache: false, // defaults to true
      },
    }
  • You can control the “Cache-Control” header which was previously always overwritten with the internal values ​​of next.js. This caused artifacts with caching via CDN;
  •  next/dynamic caches modules for reuse, rather than loading again each time;

Partial Prerendering (PPR)

This could be the main teaser of the release. PPR is a page assembly mode, in which Next.Js prerenders and caches as much of the route as possible,. while some individual elements are built on each request. In this case, the pre-assembled part is immediately sent to the client, and the remaining are loaded dynamically.

Partially Prerendered Product Page showing static nav and product information, and dynamic cart and recommended products

PPR diagram from the official documentation

The feature existed already six months ago in the release candidate as an experimental API. Previously PPR was enabled for the entire project, but since now it one can enable it for each segment (layout or page):

export const experimental_ppr = true

Another change is Partial Fallback Prerendering (PFPR). Due to this improvement, the pre-assembled part is immediately sent to the client, and the rest are loaded dynamically. At this time, a callback component is shown in place of the dynamic elements.

import { Suspense } from "react"
import { StaticComponent, DynamicComponent } from "@/app/ui"
 
export const experimental_ppr = true
 
export default function Page() {
  return {
     <>
         <StaticComponent />
         <Suspense fallback={...}>
             <DynamicComponent />
         </Suspense>
     </>
  };
}

Instrumentation

Instrumentation comes as a stable API. The instrumentation file allows users to affect Next.js server lifecycle. Works universally with all Pages Router and App Router segments.

Currently, instrumentation supports hooks:

  • register – called once when initializing the next.js server. Can be used for integration with monitoring libraries (OpenTelemetry, datalog) or for specific project tasks.
  • onRequestError – a new hook called on all server errors. Can be used for integration with error tracking libraries (Sentry).

Interceptor

Interceptor is route-level middleware. It feels as something like a full-fledged existing middleware, but, unlike the one:

  • Can work in node.js runtime;
  • Works on the server, therefore has access to the environment and a single cache;
  • Can be added multiple times and is nesting inherited (like middleware worked when it was in beta);
  • Works, among other things, for server functions.

In this case, when creating an interceptor file, all pages underneath the tree become dynamic.

  • If we keep Vercel in mind, now middleware will be effective as a primary simple check at the CDN level (so that it could immediately return redirects if the request is not allowed), and interceptors will work on the server, doing full checks and complex operations.
  • For the self-host, apparently, such a division will be less effective since both abstractions work on the server. Perhaps it will be enough just to use only interceptor.

Welcome v0 – Vercel’s new Generative UI

Img 20241024 154822

Last but not least, Next.js introduces Generative UI (v0), a groundbreaking feature that combines the best practices of frontend development with the full potential of generative AI. Currently in Beta, I had the opportunity to experience Generative UI firsthand at the event. I was thrilled to see how powerful and intuitive it is—from the very first prompt, it successfully generated the configuration for Sitecore!

Img 20241024 155506

I am thrilled to conclude that our toolbelt has been enriched with new, practical tools that enable us to deliver exceptional solutions effortlessly, eliminating the need to reinvent the wheel.

Well done, Vercel! Thanks everyone building this wonderful ecosystem:

Img 20241024 101237

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Martin Miles

Martin is a Sitecore Expert and .NET technical solution architect involved in producing enterprise web and mobile applications, with 20 years of overall commercial development experience. Since 2010 working exclusively with Sitecore as a digital platform. With excellent knowledge of XP, XC, and SaaS / Cloud offerings from Sitecore, he participated in more than 20 successful implementations, producing user-friendly and maintainable systems for clients. Martin is a prolific member of the Sitecore community. He is the author and creator of the Sitecore Link project and one of the best tools for automating Sitecore development and maintenance - Sifon. He is also the founder of the Sitecore Discussion Club and, co-organizer of the Los Angeles Sitecore user group, creator of the Sitecore Telegram channel that has brought the best insight from the Sitecore world since late 2017.

More from this Author

Follow Us