BackZurück zum Blog

Next.js 14

Next.js 14 bietet verbesserte Performance, Stabilität für Server Actions, einen neuen Kurs zum App Router und mehr.

Wie wir auf der Next.js Conf angekündigt haben, ist Next.js 14 unser fokussiertes Release mit:

  • Turbopack: 5.000 bestandene Tests für App & Pages Router
    • 53% schnellere lokale Serverstartzeit
    • 94% schnellere Code-Updates mit Fast Refresh
  • Server Actions (Stable): Progressiv verbesserte Mutationen
    • Integration mit Caching & Revalidierung
    • Einfache Funktionsaufrufe oder native Formularintegration
  • Partial Prerendering (Preview): Schnelle statische Initialantwort + dynamische Inhalte im Stream
  • Next.js Learn (Neu): Kostenloser Kurs zum App Router, Authentifizierung, Datenbanken und mehr.

Jetzt aktualisieren oder starten mit:

Terminal
npx create-next-app@latest

Next.js Compiler: Turbocharged

Seit Next.js 13 arbeiten wir daran, die lokale Entwicklungsperformance in Next.js für beide Router (Pages und App) zu verbessern.

Ursprünglich haben wir next dev und andere Teile von Next.js für diesen Zweck neu geschrieben. Wir haben unseren Ansatz jedoch zu einem inkrementelleren Vorgehen geändert. Das bedeutet, dass unser Rust-basierter Compiler bald stabil sein wird, da wir uns zunächst auf die Unterstützung aller Next.js-Funktionen konzentriert haben.

5.000 Integrationstests für next dev werden nun mit Turbopack, unserer zugrundeliegenden Rust-Engine, bestanden. Diese Tests umfassen 7 Jahre an Bugfixes und Reproduktionen.

Bei Tests auf vercel.com, einer großen Next.js-Anwendung, haben wir folgendes festgestellt:

  • Bis zu 53,3% schnellere lokale Serverstartzeit
  • Bis zu 94,7% schnellere Code-Updates mit Fast Refresh

Dieses Benchmark ist ein praktisches Ergebnis der Performance-Verbesserungen, die Sie bei einer großen Anwendung (und einem großen Modulgraphen) erwarten können. Da nun 90% der Tests für next dev bestanden werden, sollten Sie konsistent schnellere und zuverlässigere Performance bei der Verwendung von next dev --turbo feststellen.

Sobald wir 100% der bestandenen Tests erreichen, werden wir Turbopack in einem kommenden Minor-Release als stabil einstufen. Wir werden weiterhin Webpack für benutzerdefinierte Konfigurationen und Ökosystem-Plugins unterstützen.

Den Fortschritt der bestandenen Tests können Sie unter areweturboyet.com verfolgen.

Formulare und Mutationen

Next.js 9 führte API Routes ein - eine Möglichkeit, Backend-Endpoints schnell neben Ihrem Frontend-Code zu erstellen.

Beispielsweise würden Sie eine neue Datei im api/-Verzeichnis erstellen:

pages/api/submit.ts
import type { NextApiRequest, NextApiResponse } from 'next';
 
export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse,
) {
  const data = req.body;
  const id = await createItem(data);
  res.status(200).json({ id });
}

Auf der Client-Seite könnten Sie dann React und einen Event-Handler wie onSubmit verwenden, um einen fetch an Ihre API Route durchzuführen.

pages/index.tsx
import { FormEvent } from 'react';
 
export default function Page() {
  async function onSubmit(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
 
    const formData = new FormData(event.currentTarget);
    const response = await fetch('/api/submit', {
      method: 'POST',
      body: formData,
    });
 
    // Antwort bei Bedarf verarbeiten
    const data = await response.json();
    // ...
  }
 
  return (
    <form onSubmit={onSubmit}>
      <input type="text" name="name" />
      <button type="submit">Submit</button>
    </form>
  );
}

Mit Next.js 14 möchten wir die Developer Experience bei der Erstellung von Datenmutationen vereinfachen. Zudem wollen wir die Nutzererfahrung bei langsamen Netzwerkverbindungen oder Formularübermittlungen von leistungsschwächeren Geräten verbessern.

Server Actions (Stable)

Was wäre, wenn Sie keine manuelle API Route erstellen müssten? Stattdessen könnten Sie eine Funktion definieren, die sicher auf dem Server läuft und direkt von Ihren React-Komponenten aufgerufen wird.

Der App Router basiert auf dem React canary-Kanal, der stabil für Frameworks zur Übernahme neuer Funktionen ist. Ab v14 hat Next.js auf das neueste React canary aktualisiert, das stabile Server Actions enthält.

Das vorherige Beispiel aus dem Pages Router kann auf eine Datei vereinfacht werden:

app/page.tsx
export default function Page() {
  async function create(formData: FormData) {
    'use server';
    const id = await createItem(formData);
  }
 
  return (
    <form action={create}>
      <input type="text" name="name" />
      <button type="submit">Submit</button>
    </form>
  );
}

Server Actions sollten für Entwickler, die bereits serverzentrierte Frameworks verwendet haben, vertraut wirken. Es basiert auf Web-Fundamenten wie Formularen und der FormData Web API.

Während die Verwendung von Server Actions über ein Formular für progressive Verbesserungen hilfreich ist, ist es keine Voraussetzung. Sie können sie auch direkt als Funktion aufrufen, ohne ein Formular. Bei Verwendung von TypeScript erhalten Sie so eine vollständige End-to-End-Typesicherheit zwischen Client und Server.

Datenmutationen, Neurendering der Seite oder Weiterleitungen können in einem Netzwerk-Roundtrip erfolgen, wodurch sichergestellt wird, dass die korrekten Daten auf dem Client angezeigt werden, selbst wenn der Upstream-Provider langsam ist. Zudem können Sie verschiedene Aktionen kombinieren und wiederverwenden, einschließlich vieler verschiedener Aktionen in derselben Route.

Caching, Revalidierung, Weiterleitungen und mehr

Server Actions sind tief in das gesamte App Router-Modell integriert. Sie können:

  • Gecachte Daten mit revalidatePath() oder revalidateTag() revalidieren
  • Mit redirect() zu verschiedenen Routen weiterleiten
  • Cookies mit cookies() setzen und lesen
  • Optimistische UI-Updates mit useOptimistic() handhaben
  • Fehler vom Server mit useFormState() abfangen und anzeigen
  • Ladezustände auf dem Client mit useFormStatus() anzeigen

Erfahren Sie mehr über Formulare und Mutationen mit Server Actions oder über das Sicherheitsmodell und Best Practices für Server Components und Server Actions.

Partial Prerendering (Preview)

Wir möchten einen Vorgeschmack auf Partial Prerendering geben - eine Compiler-Optimierung für dynamische Inhalte mit einer schnellen statischen Initialantwort - an der wir für Next.js arbeiten.

Partial Prerendering baut auf einem Jahrzehnt Forschung und Entwicklung zu Server-seitigem Rendering (SSR), Static-Site Generation (SSG) und inkrementeller statischer Revalidierung (ISR) auf.

Motivation

Wir haben Ihr Feedback gehört. Derzeit gibt es zu viele Laufzeitumgebungen, Konfigurationsoptionen und Rendering-Methoden, die berücksichtigt werden müssen. Sie wünschen sich die Geschwindigkeit und Zuverlässigkeit von statischen Inhalten, während gleichzeitig vollständig dynamische, personalisierte Antworten unterstützt werden.

Globale Top-Performance und Personalisierung sollten nicht auf Kosten der Komplexität gehen.

Unsere Herausforderung bestand darin, eine bessere Developer Experience zu schaffen, das bestehende Modell zu vereinfachen, ohne neue APIs für Entwickler einzuführen. Während teilweises Caching von server-seitigen Inhalten bereits existiert, müssen diese Ansätze noch die Developer Experience und Kompositionsziele erreichen, die wir anstreben.

Partial Prerendering erfordert keine neuen APIs, die gelernt werden müssen.

Auf React Suspense aufbauend

Partial Prerendering wird durch Ihre Suspense-Grenzen definiert. So funktioniert es. Betrachten Sie die folgende E-Commerce-Seite:

app/page.tsx
export default function Page() {
  return (
    <main>
      <header>
        <h1>My Store</h1>
        <Suspense fallback={<CartSkeleton />}>
          <ShoppingCart />
        </Suspense>
      </header>
      <Banner />
      <Suspense fallback={<ProductListSkeleton />}>
        <Recommendations />
      </Suspense>
      <NewProducts />
    </main>
  );
}

Bei aktiviertem Partial Prerendering generiert diese Seite eine statische Shell basierend auf Ihren <Suspense />-Grenzen. Der fallback von React Suspense wird vorgerendert.

Die Suspense-Fallbacks in der Shell werden dann durch dynamische Komponenten ersetzt, wie das Lesen von Cookies zur Bestimmung des Warenkorbs oder das Anzeigen eines Banners basierend auf dem Benutzer.

Wenn eine Anfrage gestellt wird, wird die statische HTML-Shell sofort ausgeliefert:

<main>
  <header>
    <h1>My Store</h1>
    <div class="cart-skeleton">
      <!-- Hole -->
    </div>
  </header>
  <div class="banner" />
  <div class="product-list-skeleton">
    <!-- Hole -->
  </div>
  <section class="new-products" />
</main>

Da <ShoppingCart /> aus cookies liest, um die Benutzersitzung zu überprüfen, wird diese Komponente dann als Teil derselben HTTP-Anfrage wie die statische Shell eingestreamt. Es sind keine zusätzlichen Netzwerk-Roundtrips erforderlich.

app/cart.tsx
import { cookies } from 'next/headers'
 
export default function ShoppingCart() {
  const cookieStore = cookies()
  const session = cookieStore.get('session')
  return ...
}

Um die granularste statische Shell zu erhalten, kann dies das Hinzufügen zusätzlicher Suspense-Grenzen erfordern. Wenn Sie jedoch bereits loading.js verwenden, handelt es sich hierbei um eine implizite Suspense-Grenze, sodass keine Änderungen erforderlich wären, um die statische Shell zu generieren.

Demnächst verfügbar

Partielles Prerendering befindet sich in aktiver Entwicklung. Weitere Updates folgen in einem kommenden Minor-Release.

Verbesserungen bei Metadaten

Bevor der Seiteninhalt vom Server gestreamt werden kann, müssen wichtige Metadaten wie Viewport, Farbschema und Theme zuerst an den Browser gesendet werden.

Die Sicherstellung, dass diese meta-Tags mit dem initialen Seiteninhalt gesendet werden, gewährleistet eine flüssige Nutzererfahrung, indem sie verhindern, dass die Seite durch Änderungen der Theme-Farbe flackert oder das Layout sich durch Viewport-Anpassungen verschiebt.

In Next.js 14 haben wir blockierende und nicht-blockierende Metadaten entkoppelt. Nur eine kleine Teilmenge der Metadaten-Optionen ist blockierend, und wir stellen sicher, dass nicht-blockierende Metadaten das Ausliefern der statischen Shell bei partiell prerenderten Seiten nicht verhindern.

Die folgenden Metadaten-Optionen sind nun veraltet und werden in einer zukünftigen Major-Version aus metadata entfernt:

  • viewport: Legt den initialen Zoom und andere Eigenschaften des Viewports fest
  • colorScheme: Legt die unterstützten Modi (hell/dunkel) für den Viewport fest
  • themeColor: Legt die Farbe fest, mit der die Chrome-Umgebung des Viewports gerendert werden soll

Ab Next.js 14 gibt es neue Optionen viewport und generateViewport, die diese ersetzen. Alle anderen metadata-Optionen bleiben unverändert.

Sie können diese neuen APIs bereits jetzt verwenden. Die bestehenden metadata-Optionen funktionieren weiterhin.

Next.js Learn Kurs

Heute veröffentlichen wir einen brandneuen, kostenlosen Kurs auf Next.js Learn. Dieser Kurs behandelt:

  • Den Next.js App Router
  • Styling und Tailwind CSS
  • Optimierung von Schriftarten und Bildern
  • Erstellung von Layouts und Seiten
  • Navigation zwischen Seiten
  • Einrichtung einer Postgres-Datenbank
  • Datenabfrage mit Server Components
  • Statisches und dynamisches Rendering
  • Streaming
  • Partielles Prerendering (Optional)
  • Hinzufügen von Suche und Paginierung
  • Datenmutation
  • Fehlerbehandlung
  • Verbesserung der Barrierefreiheit
  • Hinzufügen von Authentifizierung
  • Hinzufügen von Metadaten

Next.js Learn hat bereits Millionen von Entwicklern die Grundlagen des Frameworks vermittelt, und wir freuen uns auf Ihr Feedback zu unserer neuen Ergänzung. Besuchen Sie nextjs.org/learn, um den Kurs zu starten.

Weitere Änderungen

  • [Breaking] Die Mindestversion von Node.js ist nun 18.17
  • [Breaking] Entfernung des WASM-Targets für next-swc-Build (PR)
  • [Breaking] Unterstützung für @next/font zugunsten von next/font eingestellt (Codemod)
  • [Breaking] Änderung des ImageResponse-Imports von next/server zu next/og (Codemod)
  • [Breaking] Der Befehl next export wurde zugunsten der Konfiguration output: 'export' entfernt (Docs)
  • [Deprecation] onLoadingComplete für next/image ist veraltet und wird durch onLoad ersetzt
  • [Deprecation] domains für next/image ist veraltet und wird durch remotePatterns ersetzt
  • [Feature] Detailliertere Protokollierung rund um fetch-Caching kann aktiviert werden (Docs)
  • [Improvement] 80% kleinere Funktionsgröße für eine grundlegende create-next-app-Anwendung
  • [Improvement] Verbessertes Speichermanagement bei Verwendung des edge-Runtimes in der Entwicklung

Mitwirkende

Next.js ist das Ergebnis der gemeinsamen Arbeit von über 2.900 individuellen Entwicklern, Industriepartnern wie Google und Meta sowie unserem Kernteam bei Vercel. Treten Sie der Community bei auf GitHub Discussions, Reddit und Discord.

Dieses Release wurde ermöglicht durch:

Und die Beiträge von: @05lazy, @0xadada, @2-NOW, @aarnadlr, @aaronbrown-vercel, @aaronjy, @abayomi185, @abe1272001, @abhiyandhakal, @abstractvector, @acdlite, @adamjmcgrath, @AdamKatzDev, @adamrhunter, @ademilter, @adictonator, @adilansari, @adtc, @afonsojramos, @agadzik, @agrattan0820, @akd-io, @AkifumiSato, @akshaynox, @alainkaiser, @alantoa, @albertothedev, @AldeonMoriak, @aleksa-codes, @alexanderbluhm, @alexkirsz, @alfred-mountfield, @alpha-xek, @andarist, @Andarist, @andrii-bodnar, @andykenward, @angel1254mc, @anonrig, @anthonyshew, @AntoineBourin, @anujssstw, @apeltop, @aralroca, @aretrace, @artdevgame, @artechventure, @arturbien, @Aryan9592, @AviAvinav, @aziyatali, @BaffinLee, @Banbarashik, @bencmbrook, @benjie, @bennettdams, @bertho-zero, @bigyanse, @Bitbbot, @blue-devil1134, @bot08, @bottxiang, @Bowens20832, @bre30kra69cs, @BrennanColberg, @brkalow, @BrodaNoel, @Brooooooklyn, @brunoeduardodev, @brvnonascimento, @carlos-menezes, @cassidoo, @cattmote, @cesarkohl, @chanceaclark, @charkour, @charlesbdudley, @chibicode, @chrisipanaque, @ChristianIvicevic, @chriswdmr, @chunsch, @ciruz, @cjmling, @clive-h-townsend, @colinhacks, @colinking, @coreyleelarson, @Cow258, @cprussin, @craigwheeler, @cramforce, @cravend, @cristobaldominguez95, @ctjlewis, @cvolant, @cxa, @danger-ahead, @daniel-web-developer, @danmindru, @dante-robinson, @darshanjain-entrepreneur, @darshkpatel, @davecarlson, @David0z, @davidnx, @dciug, @delbaoliveira, @denchance, @DerTimonius, @devagrawal09, @DevEsteves, @devjiwonchoi, @devknoll, @DevLab2425, @devvspaces, @didemkkaslan, @dijonmusters, @dirheimerb, @djreillo, @dlehmhus, @doinki, @dpnolte, @Drblessing, @dtinth, @ducanhgh, @DuCanhGH, @ductnn, @duncanogle, @dunklesToast, @DustinsCode, @dvakatsiienko, @dvoytenko, @dylanjha, @ecklf, @EndangeredMassa, @eps1lon, @ericfennis, @escwxyz, @Ethan-Arrowood, @ethanmick, @ethomson, @fantaasm, @feikerwu, @ferdingler, @FernandVEYRIER, @feugy, @fgiuliani, @fomichroman, @Fonger, @ForsakenHarmony, @franktronics, @FSaldanha, @fsansalvadore, @furkanmavili, @g12i, @gabschne, @gaojude, @gdborton, @gergelyke, @gfgabrielfranca, @gidgudgod, @Gladowar, @Gnadhi, @gnoff, @goguda, @greatSumini, @gruz0, @Guilleo03, @gustavostz, @hanneslund, @HarshaVardhanReddyDuvvuru, @haschikeks, @Heidar-An, @heyitsuzair, @hiddenest, @hiro0218, @hotters, @hsrvms, @hu0p, @hughlilly, @HurSungYun, @hustLer2k, @iamarpitpatidar, @ianldgs, @ianmacartney, @iaurg, @ibash, @ibrahemid, @idoob, @iiegor, @ikryvorotenko, @imranbarbhuiya, @ingovals, @inokawa, @insik-han, @isaackatayev, @ishaqibrahimbot, @ismaelrumzan, @itsmingjie, @ivanhofer, @IvanKiral, @jacobsfletch, @jakemstar, @jamespearson, @JanCizmar, @janicklas-ralph, @jankaifer, @JanKaifer, @jantimon, @jaredpalmer, @javivelasco, @jayair, @jaykch, @Jeffrey-Zutt, @jenewland1999, @jeremydouglas, @JesseKoldewijn, @jessewarren-aa, @jimcresswell, @jiwooIncludeJeong, @jocarrd, @joefreeman, @JohnAdib, @JohnAlbin, @JohnDaly, @johnnyomair, @johnta0, @joliss, @jomeswang, @joostdecock, @Josehower, @josephcsoti, @josh, @joshuabaker, @JoshuaKGoldberg, @joshuaslate, @joulev, @jsteele-stripe, @JTaylor0196, @JuanM04, @jueungrace, @juliusmarminge, @Juneezee, @Just-Moh-it, @juzhiyuan, @jyunhanlin, @kaguya3222, @karlhorky, @kevinmitch14, @keyz, @kijikunnn, @kikobeats, @Kikobeats, @kleintorres, @koba04, @koenpunt, @koltong, @konomae, @kosai106, @krmeda, @kvnang, @kwonoj, @ky1ejs, @kylemcd, @labyrinthitis, @lachlanjc, @lacymorrow, @laityned, @Lantianyou, @leerob, @leodr, @leoortizz, @li-jia-nan, @loettz, @lorenzobloedow, @lubakravche, @lucasassisrosa, @lucasconstantino, @lucgagan, @LukeSchlangen, @LuudJanssen, @lycuid, @M3kH, @m7yue, @manovotny, @maranomynet, @marcus-rise, @MarDi66, @MarkAtOmniux, @martin-wahlberg, @masnormen, @matepapp, @matthew-heath, @mattpr, @maxleiter, @MaxLeiter, @maxproske, @meenie, @meesvandongen, @mhmdrioaf, @michaeloliverx, @mike-plummer, @MiLk, @milovangudelj, @Mingyu-Song, @mirismaili, @mkcy3, @mknichel, @mltsy, @mmaaaaz, @mnajdova, @moetazaneta, @mohanraj-r, @molebox, @morganfeeney, @motopods, @mPaella, @mrkldshv, @mrxbox98, @nabsul, @nathanhammond, @nbouvrette, @nekochantaiwan, @nfinished, @Nick-Mazuk, @nickmccurdy, @niedziolkamichal, @niko20, @nikolovlazar, @nivak-monarch, @nk980113, @nnnnoel, @nocell, @notrab, @nroland013, @nuta, @nutlope, @obusk, @okcoker, @oliviertassinari, @omarhoumz, @opnay, @orionmiz, @ossan-engineer, @patrick91, @pauek, @peraltafederico, @Phiction, @pn-code, @pyjun01, @pythagoras-yamamoto, @qrohlf, @raisedadead, @reconbot, @reshmi-sriram, @reyrodrigez, @ricardofiorani, @rightones, @riqwan, @rishabhpoddar, @rjsdnql123, @rodrigofeijao, @runjuu, @Ryan-Dia, @ryo-manba, @s0h311, @sagarpreet-xflowpay, @sairajchouhan, @samdenty, @samsisle, @sanjaiyan-dev, @saseungmin, @SCG82, @schehata, @Schniz, @sepiropht, @serkanbektas, @sferadev, @ShaunFerris, @shivanshubisht, @shozibabbas, @silvioprog, @simonswiss, @simPod, @sivtu, @SleeplessOne1917, @smaeda-ks, @sonam-serchan, @SonMooSans, @soonoo, @sophiebits, @souporserious, @sp00ls, @sqve, @sreetamdas, @stafyniaksacha, @starunaway, @steebchen, @stefanprobst, @steppefox, @steven-tey, @suhaotian, @sukkaw, @SukkaW, @superbahbi, @SuttonJack, @svarunid, @swaminator, @swarnava, @syedtaqi95, @taep96, @taylorbryant, @teobler, @Terro216, @theevilhead, @thepatrick00, @therealrinku, @thomasballinger, @thorwebdev, @tibi1220, @tim-hanssen, @timeyoutakeit, @tka5, @tknickman, @tomryanx, @trigaten, @tristndev, @tunamagur0, @tvthatsme, @tyhopp, @tyler-lutz, @UnknownMonk, @v1k1, @valentincostam, @valentinh, @valentinpolitov, @vamcs, @vasucp1207, @vicsantizo, @vinaykulk621, @vincenthongzy, @visshaljagtap, @vladikoff, @wherehows, @WhoAmIRUS, @WilderDev, @Willem-Jaap, @williamli, @wiredacorn, @wiscaksono, @wojtekolek, @ws-jm, @wxh06, @wyattfry, @wyattjoh, @xiaolou86, @y-tsubuku, @yagogmaisp, @yangshun, @yasath, @Yash-Singh1, @yigithanyucedag, @ykzts, @Yovach, @yutsuten, @yyuemii, @zek, @zekicaneksi, @zignis, und @zlrlyy