Skip to content
Back to Blog

Thursday, January 18th 2024

Next.js 14.1

Posted by

Next.js 14.1 includes developer experience improvements including:

Upgrade today or get started with:

Terminal
npx create-next-app@latest

Improved Self-Hosting

We've heard your feedback for improved clarity on how to self-host Next.js with a Node.js server, Docker container, or static export. We've overhauled our self-hosting documentation on:

With Next.js 14.1, we've also stabilized providing custom cache handlers for Incremental Static Regeneration and the more granular Data Cache for the App Router:

next.config.js
module.exports = {
  cacheHandler: require.resolve('./cache-handler.js'),
  cacheMaxMemorySize: 0, // disable default in-memory caching
};

Using this configuration when self-hosting is important when using container orchestration platforms like Kubernetes, where each pod will have a copy of the cache. Using a custom cache handler will allow you to ensure consistency across all pods hosting your Next.js application.

For instance, you can save the cached values anywhere, like Redis or Memcached. We'd like to thank @neshca for their Redis cache handler adapter and example.

Turbopack Improvements

We're continuing to focus on the reliability and performance of local Next.js development:

  • Reliability: Turbopack passing the entire Next.js development test suite and dogfooding Vercel's applications
  • Performance: Improving Turbopack initial compile times and Fast Refresh times
  • Memory Usage: Improving Turbopack memory usage

We plan to stabilize next dev --turbo in an upcoming release with it still being opt-in.

Reliability

Next.js with Turbopack now passes 5,600 development tests (94%), 600 more since the last update. You can follow the progress on areweturboyet.com.

We have continued dogfooding next dev --turbo on all Vercel's Next.js applications, including vercel.com and v0.dev. All engineers working on these applications are using Turbopack daily.

We've found and fixed a number of issues for very large Next.js applications using Turbopack. For these fixes, we've added new tests to the existing development test suites in Next.js.

Performance

For vercel.com, a large Next.js application, we've seen:

  • Up to 76.7% faster local server startup
  • Up to 96.3% faster code updates with Fast Refresh
  • Up to 45.8% faster initial route compile without caching (Turbopack does not have disk caching yet)

In v0.dev, we identified an opportunity to optimize the way React Client Components are discovered and bundled in Turbopack - resulting in up to 61.5% faster initial compile time. This performance improvement was also observed in vercel.com.

Future Improvements

Turbopack currently has in-memory caching, which improves incremental compilation times for Fast Refresh.

However, the cache is currently not preserved when restarting the Next.js development server. The next big step for Turbopack performance is disk caching, which will allow the cache to be preserved when restating the development server.

Developer Experience Improvements

Improved Error Messages and Fast Refresh

We know how critical clear error messages are to your local development experience. We've made a number of fixes to improve the quality of stack traces and error messages you see when running next dev.

  • Errors that previously displayed bundler errors like webpack-internal now properly display the source code of the error and the affected file.
  • After seeing an error in a client component, and then fixing the error in your editor, the Fast Refresh did not clear the error screen. It required a hard reload. We've fixed a number of these instances. For example, trying to export metadata from a Client Component.

For example, this was a previous error message:

An example of an error from a fetch call in Next.js 14.
An example of an error from a fetch call in Next.js 14.

Next.js 14.1 has improved this to:

Errors from fetch calls during rendering now display the source code of the error and the affected file.
Errors from fetch calls during rendering now display the source code of the error and the affected file.

window.history.pushState and window.history.replaceState

The App Router now allows the usage of the native pushState and replaceState methods to update the browser's history stack without reloading the page.

pushState and replaceState calls integrate into the Next.js App Router, allowing you to sync with usePathname and useSearchParams.

This is helpful when needing to immediately update the URL when saving state like filters, sort order, or other information desired to persist across reloads.

'use client';
 
import { useSearchParams } from 'next/navigation';
 
export default function SortProducts() {
  const searchParams = useSearchParams();
 
  function updateSorting(sortOrder: string) {
    const params = new URLSearchParams(searchParams.toString());
    params.set('sort', sortOrder);
    window.history.pushState(null, '', `?${params.toString()}`);
  }
 
  return (
    <>
      <button onClick={() => updateSorting('asc')}>Sort Ascending</button>
      <button onClick={() => updateSorting('desc')}>Sort Descending</button>
    </>
  );
}

Learn more about using the native History API with Next.js.

Data Cache Logging

For improved observability of your cached data in your Next.js application when running next dev, we've made a number of improvements to the logging configuration option.

You can now display whether there was a cache HIT or SKIP and the full URL requested:

Terminal
GET / 200 in 48ms
Compiled /fetch-cache in 117ms
 GET /fetch-cache 200 in 165ms
GET https://api.vercel.app/products/1 200 in 14ms (cache: HIT)
Compiled /fetch-no-store in 150ms
 GET /fetch-no-store 200 in 548ms
GET https://api.vercel.app/products/1 200 in 345ms (cache: SKIP)
  Cache missed reason: (cache: no-store)

This can be enabled through next.config.js:

next.config.js
module.exports = {
  logging: {
    fetches: {
      fullUrl: true,
    },
  },
};

next/image support for <picture> and Art Direction

The Next.js Image component now supports more advanced use cases through getImageProps() (stable) which don't require using <Image> directly. This includes:

import { getImageProps } from 'next/image';
 
export default function Page() {
  const common = { alt: 'Hero', width: 800, height: 400 };
  const {
    props: { srcSet: dark },
  } = getImageProps({ ...common, src: '/dark.png' });
  const {
    props: { srcSet: light, ...rest },
  } = getImageProps({ ...common, src: '/light.png' });
 
  return (
    <picture>
      <source media="(prefers-color-scheme: dark)" srcSet={dark} />
      <source media="(prefers-color-scheme: light)" srcSet={light} />
      <img {...rest} />
    </picture>
  );
}

Learn more about getImageProps().

Parallel & Intercepted Routes

In Next.js 14.1, we've made 20 improvements to Parallel & Intercepted Routes.

For the past two releases, we've been focused on improving performance and reliability of Next.js. We've now been able to make many improvements to Parallel & Intercepted Routes based on your feedback. Notably, we've added support for catch-all routes and Server Actions.

  • Parallel Routes allow you to simultaneously or conditionally render one or more pages in the same layout. For highly dynamic sections of an app, such as dashboards and feeds on social sites, Parallel Routes can be used to implement complex routing patterns.
  • Intercepted Routes allow you to load a route from another part of your application within the current layout. For example, when clicking on a photo in a feed, you can display the photo in a modal, overlaying the feed. In this case, Next.js intercepts the /photo/123 route, masks the URL, and overlays it over /feed.

Learn more about Parallel & Intercepted Routes or view an example.

Other Improvements

Since 14.0, we've fixed a number of highly upvoted bugs from the community.

We've also recently published videos explaining caching and some common mistakes with the App Router that you might find helpful.

  • [Docs] New documentation on Redirecting
  • [Docs] New documentation on Testing
  • [Docs] New documentation with a Production Checklist
  • [Feature] Add <GoogleAnalytics /> component to next/third-parties (Docs)
  • [Improvement] create-next-app is now smaller and faster to install (PR)
  • [Improvement] Nested routes throwing errors can still be caught be global-error (PR)
  • [Improvement] redirect now respects basePath when used in a server action (PR)
  • [Improvement] Fix next/script and beforeInteractive usage with App Router (PR)
  • [Improvement] Automatically transpile @aws-sdk and lodash for faster route startup (PR)
  • [Improvement] Fix flash of unstyled content with next dev and next/font (PR)
  • [Improvement] Propagate notFound errors past a segment's error boundary (PR)
  • [Improvement] Fix serving public files from locale domains with Pages Router i18n (PR)
  • [Improvement] Error if an invalidate revalidate value is passed (PR)
  • [Improvement] Fix path issues on linux machines when build created on windows (PR)
  • [Improvement] Fix Fast Refresh / HMR when using a multi-zone app with basePath (PR)
  • [Improvement] Improve graceful shutdown from termination signals (PR)
  • [Improvement] Modal routes clash when intercepting from different routes (PR)
  • [Improvement] Fix intercepting routes when using basePath config (PR)
  • [Improvement] Show warning when a missing parallel slot results in 404 (PR)
  • [Improvement] Improve intercepted routes when used with catch-all routes (PR)
  • [Improvement] Improve intercepted routes when used with revalidatePath (PR)
  • [Improvement] Fix usage of @children slots with parallel routes (PR)
  • [Improvement] Fix Fix TypeError when using params with parallel routes (PR)
  • [Improvement] Fix catch-all route normalization for default parallel routes (PR)
  • [Improvement] Fix display of parallel routes in the next build summary (PR)
  • [Improvement] Fix for route parameters when using intercepted routes (PR)
  • [Improvement] Improve deeply nested parallel/intercepted routes (PR)
  • [Improvement] Fix 404 with intercepted routes paired with route groups (PR)
  • [Improvement] Fix parallel routes with server actions / revalidating router cache (PR)
  • [Improvement] Fix usage of rewrites with an intercepted route (PR)
  • [Improvement] Server Actions now work from third-party libraries (PR)
  • [Improvement] Next.js can now be used within an ESM package (PR)
  • [Improvement] Barrel file optimizations for libraries like Material UI (PR)
  • [Improvement] Builds will now fail on incorrect usage of useSearchParams without Suspense (PR)

Contributors

Next.js is the result of the combined work of over 3,000 individual developers, industry partners like Google and Meta, and our core team at Vercel. Join the community on GitHub Discussions, Reddit, and Discord.

This release was brought to you by:

And the contributions of: @OlehDutchenko, @eps1lon, @ebidel, @janicklas-ralph, @JohnPhamous, @chentsulin, @akawalsky, @BlankParticle, @dvoytenko, @smaeda-ks, @kenji-webdev, @rv-david, @icyJoseph, @dijonmusters, @A7med3bdulBaset, @jenewland1999, @mknichel, @kdy1, @housseindjirdeh, @max-programming, @redbmk, @SSakibHossain10, @jamesmillerburgess, @minaelee, @officialrajdeepsingh, @LorisSigrist, @yesl-kim, @StevenKamwaza, @manovotny, @mcexit, @remcohaszing, @ryo-manba, @TranquilMarmot, @vinaykulk621, @haritssr, @divquan, @IgorVaryvoda, @LukeSchlangen, @RiskyMH, @ash2048, @ManuWeb3, @msgadi, @dhayab, @ShahriarKh, @jvandenaardweg, @DestroyerXyz, @SwitchBladeAK, @ianmacartney, @justinh00k, @tiborsaas, @ArianHamdi, @li-jia-nan, @aramikuto, @jquinc30, @samcx, @Haosik, @AkifumiSato, @arnabsen, @nfroidure, @clbn, @siddtheone, @zbauman3, @anthonyshew, @alexfradiani, @CalebBarnes, @adk96r, @pacexy, @hichemfantar, @michaldudak, @redonkulus, @k-taro56, @mhughdo, @tknickman, @shumakmanohar, @vordgi, @hamirmahal, @gaspar09, @JCharante, @sjoerdvanBommel, @mass2527, @N-Ziermann, @tordans, @davidthorand, @rmathew8-gh, @chriskrogh, @shogunsea, @auipga, @SukkaW, @agustints, @OXXD, @clarencepenz, @better-salmon, @808vita, @coltonehrman, @tksst, @hugo-syn, @JakobJingleheimer, @Willem-Jaap, @brandonnorsworthy, @jaehunn, @jridgewell, @gtjamesa, @mugi-uno, @kentobento, @vivianyentran, @empflow, @samennis1, @mkcy3, @suhaotian, @imevanc, @d3lm, @amannn, @hallatore, @Dylan700, @mpsq, @mdio, @christianvuerings, @karlhorky, @simonhaenisch, @olci34, @zce, @LavaToaster, @rishabhpoddar, @jirihofman, @codercor, @devjiwonchoi, @JackieLi565, @thoushif, @pkellner, @jpfifer, @quisido, @tomfa, @raphaelbadia, @j9141997, @hongaar, @MadCcc, @luismulinari, @dumb-programmer, @nonoakij, @franky47, @robbertstevens, @bryndyment, @marcosmartini, @functino, @Anisi, @AdonisAgelis, @seangray-dev, @prkagrawal, @heloineto, @kn327, @ihommani, @MrNiceRicee, @falsepopsky, @thomasballinger, @tmilewski, @Vadman97, @dnhn, @RodrigoTomeES, @sadikkuzu, @gffuma, @Schniz, @joulev, @Athrun-Judah, @rasvanjaya21, @rashidul0405, @nguyenbry, @Mwimwii, @molebox, @mrr11k, @philwolstenholme, @IgorKowalczyk, @Zoe-Bot, @HanCiHu, @JackHowa, @goncy, @hirotomoyamada, @pveyes, @yeskunall, @ChendayUP, @hmaesta, @ajz003, @its-kunal, @joelhooks, @blurrah, @tariknh, @Vinlock, @Nayeem-XTREME, @aziyatali, @aspehler, and @moka-ayumu.