;\\n}\\n
This example is more difficult. Can you spot all the dependencies which need to be part of the cache key?
\\nThe arguments index
and limit
make sense—if these values change, we select a different slice of the notifications. However, what about the user id
? It’s value is coming from the parent component.
The compiler is able to understand getNotifications
also depends on id
, and it’s value is automatically included in the cache key. This prevents an entire category of caching issues from incorrect or missing dependencies in the cache key.
Let’s revisit the last example. Could we instead use a cache()
function instead of a directive?
function Profile({ id }) {\\n async function getNotifications(index, limit) {\\n return await cache(async () => {\\n return await db\\n .select()\\n .from(notifications)\\n .limit(limit)\\n .offset(index)\\n // Oops! Where do we include id in the cache key?\\n .where(eq(notifications.userId, id));\\n });\\n }\\n \\n return <User notifications={getNotifications} />;\\n}
A cache()
function wouldn’t be able to look into the closure and see the id
value is part of the cache key. You would need to manually specify that id
is part of your key. If you forget to do so, or do it incorrectly, you risk cache collisions or stale data.
Closures can capture all sorts of local variables. A naive approach could accidentally bake in (or omit) variables you didn’t intend to. That can lead to caching the wrong data, or it might risk cache poisoning if sensitive info bleeds into the cache key.
\\n\'use cache\'
gives the compiler enough context to handle closures safely and produce cache keys correctly. A runtime-only solution, like cache()
, would require you to do everything manually—and it’s easy to make mistakes. By contrast, a directive can be statically analyzed to reliably handle all your dependencies under the hood.
We have two different types of input values to cache:
\\nLet’s say we remembered to include id
in the cache key:
await cache(async () => {\\n return await db\\n .select()\\n .from(notifications)\\n .limit(limit)\\n .offset(index)\\n .where(eq(notifications.userId, id));\\n}, [id, index, limit]);
This works if the input values can be serialized. But if id
was a React element or more complex value, we’d have to manually serialize the input keys. Consider a server component which fetches the current user based on an id
prop:
async function Profile({ id, children }) {\\n \'use cache\';\\n const user = await getUser(id);\\n \\n return (\\n <>\\n <h1>{user.name}</h1>\\n {/* Changing children doesn’t break the cache... why? */}\\n {children}\\n </>\\n );\\n}
Let’s step through how this works:
\\n\'use cache\'
and attempts to cache this componentid
can be automatically serialized, children
can not, so it instead creates a “reference”\'use cache\'
getData
is cachedchildren
This means we can safely cache just the <Profile>
component and not the children. On subsequent renders, getUser()
is not called again, but the value of children
may be different. This is composable caching.
If you’re thinking “that feels like the same model of server and client composition”—you’re absolutely right. This is sometimes called the “donut” pattern:
\\nexport default function Page() {\\n return (\\n <ServerComponent>\\n {/* Create a hole to the client */}\\n <ClientComponent />\\n <ServerComponent />\\n );\\n}
\'use cache\'
is the same. The donut is the outer component’s cached value and the hole is the references that get filled at at runtime. This is why changing children
does not invalidate the entire cached output. The children are just some reference that gets filled in later.
You can define the life of the cache with different profiles. We include a set of default profiles, but you can define your own custom values if desired.
\\nasync function getUser(id) {\\n \'use cache\';\\n cacheLife(\'hours\');\\n let res = await fetch(`https://api.vercel.app/user/${id}`);\\n return res.json();\\n}
To invalidate a specific cache entry, you can tag the cache and then call revalidateTag()
. One powerful pattern is that you can tag the cache after you have fetched your data (e.g. from a CMS):
async function getPost(postId) {\\n \'use cache\';\\n let res = await fetch(`https://api.vercel.app/blog/${postId}`);\\n let data = await res.json();\\n cacheTag(postId, data.authorId);\\n return data;\\n}
Our goal with \'use cache\'
is to make authoring caching logic simple and powerful.
\'use cache
is still experimental inside Next.js. We’d love your early feedback as you test it out.
Learn more in the documentation.
","description":"We’re working on a simple and powerful caching model for Next.js. In a previous post, we talked about our journey with caching and how we’ve arrived at the \'use cache\' directive. This post will discuss the API design and benefits of \'use cache\'.\\n\\nWhat is \'use cache\'?…","guid":"https://nextjs.org/blog/composable-caching","author":null,"authorUrl":null,"authorAvatar":null,"publishedAt":"2025-01-02T16:00:00.418Z","media":null,"categories":null,"attachments":null,"extra":null,"language":null},{"title":"Next.js 15.1","url":"https://nextjs.org/blog/next-15-1","content":"Next.js 15.1 brings core upgrades, new APIs, and improvements to the developer experience. Key updates include:
\\nafter
(stable): New API to execute code after a response has finished streaming.forbidden
/ unauthorized
(experimental): New APIs to enable more granular authentication error handling.Upgrade today, or get started with:
\\n# Use the automated upgrade CLI\\nnpx @next/codemod@canary upgrade latest\\n \\n# ...or upgrade manually\\nnpm install next@latest react@latest react-dom@latest\\n \\n# ...or start a new project\\nnpx create-next-app@latest
Next.js 15.1 now fully supports React 19:
\\nSince the Next.js 15 release, a significant addition to React 19 was “sibling pre-warming”.
\\nFor a comprehensive overview of React 19’s updates, please refer to the official React 19 blog post.
\\nWe’ve made improvements to error debugging in Next.js, ensuring you can quickly locate the source of issues, whether they appear in the terminal, browser, or attached debuggers. These enhancements apply to both Webpack and Turbopack (now stable with Next.js 15).
\\nErrors are now easier to trace back to their origin through the improved use of source maps. We’ve implemented the ignoreList
property of source maps, which allows Next.js to hide stack frames for external dependencies, making your application code the primary focus.
For slightly more accurate source mapping of method names, we suggest adopting Turbopack (now stable), which has improved handling and detection of source maps over Webpack.
\\n\\n\\nFor library authors: We recommend populating the
\\nignoreList
property in sourcemaps when publishing your libraries, especially if they are configured as external (e.g. in theserverExternalPackages
config).
We’ve improved the logic for collapsing stack frames to highlight the most relevant parts of your code.
\\nIgnored stack frames are also recognized by built-in browser profilers. This makes profiling your application easier, allowing you to pinpoint slow functions in your code without noise from external libraries.
\\nWhen using the Edge runtime, errors are now displayed consistently across development environments, ensuring seamless debugging. Previously, logged errors would only include the message and not the stack.
\\nTerminal Before:
\\n ⨯ app/page.tsx (6:11) @ eval\\n ⨯ Error: boom\\n at eval (./app/page.tsx:12:15)\\n at Page (./app/page.tsx:11:74)\\n at AsyncLocalStorage.run (node:async_hooks:346:14)\\n at stringify (<anonymous>)\\n at AsyncLocalStorage.run (node:async_hooks:346:14)\\n at AsyncResource.runInAsyncScope (node:async_hooks:206:9)\\ndigest: \\"380744807\\"\\n 4 | export default function Page() {\\n 5 | const throwError = myCallback(() => {\\n> 6 | throw new Error(\'boom\')\\n | ^\\n 7 | }, [])\\n 8 |\\n 9 | throwError()\\n GET / 500 in 2354ms
Terminal After:
\\n ⨯ Error: boom\\n at eval (app/page.tsx:6:10)\\n at Page (app/page.tsx:5:32)\\n 4 | export default function Page() {\\n 5 | const throwError = myCallback(() => {\\n> 6 | throw new Error(\'boom\')\\n | ^\\n 7 | }, [])\\n 8 |\\n 9 | throwError() {\\n digest: \'225828171\'\\n}
Error Overlay Before
\\nError Overlay After
\\nThese improvements make errors clearer and more intuitive, allowing you to focus your time building your application rather than debugging.
\\nWe’re also thrilled to announce the introduction of a redesigned UI for the error overlay, coming in upcoming releases.
\\nafter
(stable)The after()
API is now stable following its introduction in the first Next.js 15 RC.
after()
provides a way to perform tasks such as logging, analytics, and other system synchronization after the response has finished streaming to the user, without blocking the primary response.
Since its introduction, we’ve stabilized after()
and addressed feedback including:
after()
interacted with other Next.js features.waitUntil()
primitives to power after()
.cookies()
and headers()
in Server Actions and Route Handlers.import { after } from \'next/server\';\\nimport { log } from \'@/app/utils\';\\n \\nexport default function Layout({ children }) {\\n // Secondary task\\n after(() => {\\n log();\\n });\\n \\n // Primary task\\n return <>{children}</>;\\n}
Read more about the after
API and how to leverage it in the documentation.
forbidden
and unauthorized
(experimental)Next.js 15.1 includes two experimental APIs, forbidden()
and unauthorized()
, based on community feedback.
\\n\\nWe’d love your feedback — please try it in your development environments and share your thoughts in this discussion thread.
\\n
If you’re familiar with the App Router, you’ve likely used notFound()
to trigger 404 behavior alongside the customizable not-found.tsx
file. With version 15.1, we’re extending this approach to authorization errors:
• forbidden()
triggers a 403 error with customizable UI via forbidden.tsx
.
• unauthorized()
triggers a 401 error with customizable UI via unauthorized.tsx
.
\\n\\nGood to know: As with
\\nnotFound()
errors, the status code will be200
if the error is triggered after initial response headers have been sent. Learn more.
As this feature is still experimental, you’ll need to enable it in your next.config.ts
file:
import type { NextConfig } from \'next\';\\n \\nconst nextConfig: NextConfig = {\\n experimental: {\\n authInterrupts: true,\\n },\\n};\\n \\nexport default nextConfig;
\\n\\nNote:
\\nnext.config.ts
support was introduced in Next.js 15. Learn more.
forbidden()
and unauthorized()
You can use forbidden()
and unauthorized()
in Server Actions, Server Components, Client Components, or Route Handlers. Here’s an example:
import { verifySession } from \'@/app/lib/dal\';\\nimport { forbidden } from \'next/navigation\';\\n \\nexport default async function AdminPage() {\\n const session = await verifySession();\\n \\n // Check if the user has the \'admin\' role\\n if (session.role !== \'admin\') {\\n forbidden();\\n }\\n \\n // Render the admin page for authorized users\\n return <h1>Admin Page</h1>;\\n}
To customize the error pages, create the following files:
\\nimport Link from \'next/link\';\\n \\nexport default function Forbidden() {\\n return (\\n <div>\\n <h2>Forbidden</h2>\\n <p>You are not authorized to access this resource.</p>\\n <Link href=\\"/\\">Return Home</Link>\\n </div>\\n );\\n}
import Link from \'next/link\';\\n \\nexport default function Unauthorized() {\\n return (\\n <div>\\n <h2>Unauthorized</h2>\\n <p>Please log in to access this page.</p>\\n <Link href=\\"/login\\">Go to Login</Link>\\n </div>\\n );\\n}
We\'d like to thank Clerk for proposing this feature through a PR and assisting us in prototyping the API. Before we stabilize this feature in 15.2, we\'re planning on adding more capabilities and improvements to the APIs to support a wider range of use cases.
\\nRead the documentation for the unauthorized
and forbidden
APIs for more details.
create-next-app
(PR)legacy-js-api
warning (PR)Next.js is the result of the combined work of over 3,000 individual developers. This release was brought to you by:
\\nHuge thanks to @sokra, @molebox, @delbaoliveira, @eps1lon, @wbinnssmith, @JamBalaya56562, @hyungjikim, @adrian-faustino, @mottox2, @lubieowoce, @bgw, @mknichel, @wyattjoh, @huozhi, @kdy1, @mischnic, @ijjk, @icyJoseph, @acdlite, @unstubbable, @gaojude, @devjiwonchoi, @cena-ko, @lforst, @devpla, @samcx, @styfle, @ztanner, @Marukome0743, @timneutkens, @JeremieDoctrine, @ductnn, @karlhorky, @reynaldichernando, @chogyejin, @y-yagi, @philparzer, @alfawal, @Rhynden, @arlyon, @MJez29, @Goodosky, @themattmayfield, @tobySolutions, @kevinmitch14, @leerob, @emmanuelgautier, @mrhrifat, @lid0a, @boar-is, @nisabmohd, @PapatMayuri, @ovogmap, @Reflex2468, @LioRael, @betterthanhajin, @HerringtonDarkholme, @bpb54321, @ahmoin, @Kikobeats, @abdelrahmanAbouelkheir, @lumirlumir, @yeeed711, @petter, and @suu3 for helping!
","description":"Next.js 15.1 brings core upgrades, new APIs, and improvements to the developer experience. Key updates include: React 19 (stable): Support for React 19 is officially available in both Pages Router & App Router.\\nImproved Error Debugging: Enhanced DX and better source maps for the…","guid":"https://nextjs.org/blog/next-15-1","author":null,"authorUrl":null,"authorAvatar":null,"publishedAt":"2024-12-09T16:00:00.422Z","media":[{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Fnext-15-1%2Fbefore-light.png&w=2048&q=75","type":"photo","width":1000,"height":712},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Fnext-15-1%2Fbefore-dark.png&w=2048&q=75","type":"photo","width":1000,"height":712},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Fnext-15-1%2Fafter-light.png&w=2048&q=75","type":"photo","width":1000,"height":712},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Fnext-15-1%2Fafter-dark.png&w=2048&q=75","type":"photo","width":1000,"height":712}],"categories":null,"attachments":null,"extra":null,"language":null},{"title":"Next.js 15","url":"https://nextjs.org/blog/next-15","content":"Next.js 15 is officially stable and ready for production. This release builds on the updates from both RC1 and RC2. We\'ve focused heavily on stability while adding some exciting updates we think you\'ll love. Try Next.js 15 today:
\\n# Use the new automated upgrade CLI\\nnpx @next/codemod@canary upgrade latest\\n \\n# ...or upgrade manually\\nnpm install next@latest react@rc react-dom@rc
We\'re also excited to share more about what\'s coming next at Next.js Conf this Thursday, October 24th.
\\nHere\'s what is new in Next.js 15:
\\n@next/codemod
CLI: Easily upgrade to the latest Next.js and React versions.fetch
requests, GET
Route Handlers, and client navigations are no longer cached by default.unstable_after
API (Experimental): Execute code after a response finishes streaming.instrumentation.js
API (Stable): New API for server lifecycle observability.next/form
): Enhance HTML forms with client-side navigation.next.config
: TypeScript support for next.config.ts
.Cache-Control
headers.@next/codemod
CLIWe include codemods (automated code transformations) with every major Next.js release to help automate upgrading breaking changes.
\\nTo make upgrades even smoother, we\'ve released an enhanced codemod CLI:
\\nnpx @next/codemod@canary upgrade latest
This tool helps you upgrade your codebase to the latest stable or prerelease versions. The CLI will update your dependencies, show available codemods, and guide you through applying them.
\\nThe canary
tag uses the latest version of the codemod while the latest specifies the Next.js version. We recommend using the canary version of the codemod even if you are upgrading to the latest Next.js version, as we plan to continue adding improvements to the tool based on your feedback.
Learn more about Next.js codemod CLI.
\\nIn traditional Server-Side Rendering, the server waits for a request before rendering any content. However, not all components depend on request-specific data, so it\'s unnecessary to wait for the request to render them. Ideally, the server would prepare as much as possible before a request arrives. To enable this, and set the stage for future optimizations, we need to know when to wait for the request.
\\nTherefore, we are transitioning APIs that rely on request-specific data—such as headers
, cookies
, params
, and searchParams
—to be asynchronous.
import { cookies } from \'next/headers\';\\n \\nexport async function AdminPanel() {\\n const cookieStore = await cookies();\\n const token = cookieStore.get(\'token\');\\n \\n // ...\\n}
This is a breaking change and affects the following APIs:
\\ncookies
headers
draftMode
params
in layout.js
, page.js
, route.js
, default.js
, generateMetadata
, and generateViewport
searchParams
in page.js
For an easier migration, these APIs can temporarily be accessed synchronously, but will show warnings in development and production until the next major version. A codemod is available to automate the migration:
\\nnpx @next/codemod@canary next-async-request-api .
For cases where the codemod can\'t fully migrate your code, please read the upgrade guide. We have also provided an example of how to migrate a Next.js application to the new APIs.
\\nNext.js App Router launched with opinionated caching defaults. These were designed to provide the most performant option by default with the ability to opt out when required.
\\nBased on your feedback, we re-evaluated our caching heuristics and how they would interact with projects like Partial Prerendering (PPR) and with third party libraries using fetch
.
With Next.js 15, we\'re changing the caching default for fetch
requests, GET
Route Handlers, and Client Router Cache from cached by default to uncached by default. If you want to retain the previous behavior, you can continue to opt-into caching.
We\'re continuing to improve caching in Next.js in the coming months and we\'ll share more details soon.
\\nfetch
Requests are no longer cached by defaultNext.js uses the Web fetch
API cache option to configure how a server-side fetch request interacts with the framework\'s persistent HTTP cache:
fetch(\'https://...\', { cache: \'force-cache\' | \'no-store\' });
no-store
- fetch a resource from a remote server on every request and do not update the cacheforce-cache
- fetch a resource from the cache (if it exists) or a remote server and update the cacheIn Next.js 14, force-cache
was used by default if a cache
option was not provided, unless a dynamic function or dynamic config option was used.
In Next.js 15, no-store
is used by default if a cache
option is not provided. This means fetch requests will not be cached by default.
You can still opt into caching fetch
requests by:
cache
option to force-cache
in a single fetch
calldynamic
route config option to \'force-static\'
for a single routefetchCache
route config option to \'default-cache\'
to override all fetch
requests in a Layout or Page to use force-cache
unless they explicitly specify their own cache
optionGET
Route Handlers are no longer cached by defaultIn Next 14, Route Handlers that used the GET
HTTP method were cached by default unless they used a dynamic function or dynamic config option. In Next.js 15, GET
functions are not cached by default.
You can still opt into caching using a static route config option such as export dynamic = \'force-static\'
.
Special Route Handlers like sitemap.ts
, opengraph-image.tsx
, and icon.tsx
, and other metadata files remain static by default unless they use dynamic functions or dynamic config options.
In Next.js 14.2.0, we introduced an experimental staleTimes
flag to allow custom configuration of the Router Cache.
In Next.js 15, this flag still remains accessible, but we are changing the default behavior to have a staleTime
of 0
for Page segments. This means that as you navigate around your app, the client will always reflect the latest data from the Page component(s) that become active as part of the navigation. However, there are still important behaviors that remain unchanged:
loading.js
will remain cached for 5 minutes (or the value of the staleTimes.static
configuration).You can opt into the previous Client Router Cache behavior by setting the following configuration:
\\nconst nextConfig = {\\n experimental: {\\n staleTimes: {\\n dynamic: 30,\\n },\\n },\\n};\\n \\nexport default nextConfig;
As part of the Next.js 15 release, we\'ve made the decision to align with the upcoming release of React 19.
\\nIn version 15, the App Router uses React 19 RC, and we\'ve also introduced backwards compatibility for React 18 with the Pages Router based on community feedback. If you\'re using the Pages Router, this allows you to upgrade to React 19 when ready.
\\nAlthough React 19 is still in the RC phase, our extensive testing across real-world applications and our close work with the React team have given us confidence in its stability. The core breaking changes have been well-tested and won\'t affect existing App Router users. Therefore, we\'ve decided to release Next.js 15 as stable now, so your projects are fully prepared for React 19 GA.
\\nTo ensure the transition is as smooth as possible, we\'ve provided codemods and automated tools to help ease the migration process.
\\nRead the Next.js 15 upgrade guide, the React 19 upgrade guide, and watch the React Conf Keynote to learn more.
\\nNext.js 15 maintains backward compatibility for the Pages Router with React 18, allowing users to continue using React 18 while benefiting from improvements in Next.js 15.
\\nSince the first Release Candidate (RC1), we\'ve shifted our focus to include support for React 18 based on community feedback. This flexibility enables you to adopt Next.js 15 while using the Pages Router with React 18, giving you greater control over your upgrade path.
\\n\\n\\nNote: While it is possible to run the Pages Router on React 18 and the App Router on React 19 in the same application, we don\'t recommend this setup. Doing so could result in unpredictable behavior and typings inconsistencies, as the underlying APIs and rendering logic between the two versions may not fully align.
\\n
The React Compiler is a new experimental compiler created by the React team at Meta. The compiler understands your code at a deep level through its understanding of plain JavaScript semantics and the Rules of React, which allows it to add automatic optimizations to your code. The compiler reduces the amount of manual memoization developers have to do through APIs such as useMemo
and useCallback
- making code simpler, easier to maintain, and less error prone.
With Next.js 15, we\'ve added support for the React Compiler. Learn more about the React Compiler, and the available Next.js config options.
\\n\\n\\nNote: The React Compiler is currently only available as a Babel plugin, which will result in slower development and build times.
\\n
Next.js 14.1 made improvements to error messages and hydration errors. Next.js 15 continues to build on those by adding an improved hydration error view. Hydration errors now display the source code of the error with suggestions on how to address the issue.
\\nFor example, this was a previous hydration error message in Next.js 14.1:
\\nNext.js 15 has improved this to:
\\nWe are happy to announce that next dev --turbo
is now stable and ready to speed up your development experience. We\'ve been using it to iterate on vercel.com, nextjs.org, v0, and all of our other applications with great results.
For example, with vercel.com
, a large Next.js app, we\'ve seen:
You can learn more about Turbopack Dev in our new blog post.
\\nNext.js now displays a Static Route Indicator during development to help you identify which routes are static or dynamic. This visual cue makes it easier to optimize performance by understanding how your pages are rendered.
\\nYou can also use the next build output to view the rendering strategy for all routes.
\\nThis update is part of our ongoing efforts to enhance observability in Next.js, making it easier for developers to monitor, debug, and optimize their applications. We\'re also working on dedicated developer tools, with more details to come soon.
\\nLearn more about the Static Route Indicator, which can be disabled.
\\nunstable_after
(Experimental)When processing a user request, the server typically performs tasks directly related to computing the response. However, you may need to perform tasks such as logging, analytics, and other external system synchronization.
\\nSince these tasks are not directly related to the response, the user should not have to wait for them to complete. Deferring the work after responding to the user poses a challenge because serverless functions stop computation immediately after the response is closed.
\\nafter()
is a new experimental API that solves this problem by allowing you to schedule work to be processed after the response has finished streaming, enabling secondary tasks to run without blocking the primary response.
To use it, add experimental.after
to next.config.js
:
const nextConfig = {\\n experimental: {\\n after: true,\\n },\\n};\\n \\nexport default nextConfig;
Then, import the function in Server Components, Server Actions, Route Handlers, or Middleware.
\\nimport { unstable_after as after } from \'next/server\';\\nimport { log } from \'@/app/utils\';\\n \\nexport default function Layout({ children }) {\\n // Secondary task\\n after(() => {\\n log();\\n });\\n \\n // Primary task\\n return <>{children}</>;\\n}
Learn more about unstable_after
.
instrumentation.js
(Stable)The instrumentation
file, with the register()
API, allows users to tap into the Next.js server lifecycle to monitor performance, track the source of errors, and deeply integrate with observability libraries like OpenTelemetry.
This feature is now stable and the experimental.instrumentationHook
config option can be removed.
In addition, we\'ve collaborated with Sentry on designing a new onRequestError
hook that can be used to:
export async function onRequestError(err, request, context) {\\n await fetch(\'https://...\', {\\n method: \'POST\',\\n body: JSON.stringify({ message: err.message, request, context }),\\n headers: { \'Content-Type\': \'application/json\' },\\n });\\n}\\n \\nexport async function register() {\\n // init your favorite observability provider SDK\\n}
Learn more about the onRequestError
function.
<Form>
ComponentThe new <Form>
component extends the HTML <form>
element with prefetching, client-side navigation, and progressive enhancement.
It is useful for forms that navigate to a new page, such as a search form that leads to a results page.
\\nimport Form from \'next/form\';\\n \\nexport default function Page() {\\n return (\\n <Form action=\\"/search\\">\\n <input name=\\"query\\" />\\n <button type=\\"submit\\">Submit</button>\\n </Form>\\n );\\n}
The <Form>
component comes with:
Previously, achieving these features required a lot of manual boilerplate. For example:
\\n// Note: This is abbreviated for demonstration purposes.\\n// Not recommended for use in production code.\\n \\n\'use client\'\\n \\nimport { useEffect } from \'react\'\\nimport { useRouter } from \'next/navigation\'\\n \\nexport default function Form(props) {\\n const action = props.action\\n const router = useRouter()\\n \\n useEffect(() => {\\n // if form target is a URL, prefetch it\\n if (typeof action === \'string\') {\\n router.prefetch(action)\\n }\\n }, [action, router])\\n \\n function onSubmit(event) {\\n event.preventDefault()\\n \\n // grab all of the form fields and trigger a `router.push` with the data URL encoded\\n const formData = new FormData(event.currentTarget)\\n const data = new URLSearchParams()\\n \\n for (const [name, value] of formData) {\\n data.append(name, value as string)\\n }\\n \\n router.push(`${action}?${data.toString()}`)\\n }\\n \\n if (typeof action === \'string\') {\\n return <form onSubmit={onSubmit} {...props} />\\n }\\n \\n return <form {...props} />\\n}
Learn more about the <Form>
Component.
next.config.ts
Next.js now supports the TypeScript next.config.ts
file type and provides a NextConfig
type for autocomplete and type-safe options:
import type { NextConfig } from \'next\';\\n \\nconst nextConfig: NextConfig = {\\n /* config options here */\\n};\\n \\nexport default nextConfig;
Learn more about TypeScript support in Next.js.
\\nWhen self-hosting applications, you may need more control over Cache-Control
directives.
One common case is controlling the stale-while-revalidate
period sent for ISR pages. We\'ve implemented two improvements:
expireTime
value in next.config
. This was previously the experimental.swrDelta
option.stale-while-revalidate
semantics as intended.We also no longer override custom Cache-Control
values with our default values, allowing full control and ensuring compatibility with any CDN setup.
Finally, we\'ve improved image optimization when self-hosting. Previously, we recommended you install sharp
for optimizing images on your Next.js server. This recommendation was sometimes missed. With Next.js 15, you no longer need to manually install sharp
— Next.js will use sharp
automatically when using next start
or running with standalone output mode.
To learn more, see our new demo and tutorial video on self-hosting Next.js.
\\nServer Actions are server-side functions that can be called from the client. They are defined by adding the \'use server\'
directive at the top of a file and exporting an async function.
Even if a Server Action or utility function is not imported elsewhere in your code, it\'s still a publicly accessible HTTP endpoint. While this behavior is technically correct, it can lead to unintentional exposure of such functions.
\\nTo improve security, we\'ve introduced the following enhancements:
\\n// app/actions.js\\n\'use server\';\\n \\n// This action **is** used in our application, so Next.js\\n// will create a secure ID to allow the client to reference\\n// and call the Server Action.\\nexport async function updateUserAction(formData) {}\\n \\n// This action **is not** used in our application, so Next.js\\n// will automatically remove this code during `next build`\\n// and will not create a public endpoint.\\nexport async function deleteUserAction(formData) {}
You should still treat Server Actions any public HTTP endpoints. Learn more about securing Server Actions.
\\nBundling external packages can improve the cold start performance of your application. In the App Router, external packages are bundled by default, and you can opt-out specific packages using the new serverExternalPackages
config option.
In the Pages Router, external packages are not bundled by default, but you can provide a list of packages to bundle using the existing transpilePackages
option. With this configuration option, you need to specify each package.
To unify configuration between App and Pages Router, we\'re introducing a new option, bundlePagesRouterDependencies
to match the default automatic bundling of the App Router. You can then use serverExternalPackages
to opt-out specific packages, if needed.
const nextConfig = {\\n // Automatically bundle external packages in the Pages Router:\\n bundlePagesRouterDependencies: true,\\n // Opt specific packages out of bundling for both App and Pages Router:\\n serverExternalPackages: [\'package-name\'],\\n};\\n \\nexport default nextConfig;
Learn more about optimizing external packages.
\\nNext.js 15 also introduces support for ESLint 9, following the end-of-life for ESLint 8 on October 5, 2024.
\\nTo ensure a smooth transition, Next.js remain backwards compatible, meaning you can continue using either ESLint 8 or 9.
\\nIf you upgrade to ESLint 9, and we detect that you haven\'t yet adopted the new config format, Next.js will automatically apply the ESLINT_USE_FLAT_CONFIG=false
escape hatch to ease migration.
Additionally, deprecated options like —ext
and —ignore-path
will be removed when running next lint
. Please note that ESLint will eventually disallow these older configurations in ESLint 10, so we recommend starting your migration soon.
For more details on these changes, check out the migration guide.
\\nAs part of this update, we\'ve also upgraded eslint-plugin-react-hooks
to v5.0.0
, which introduces new rules for React Hooks usage. You can review all changes in the changelog for eslint-plugin-react-hooks@5.0.0.
During development, Server components are re-executed when saved. This means, any fetch
requests to your API endpoints or third-party services are also called.
To improve local development performance and reduce potential costs for billed API calls, we now ensure Hot Module Replacement (HMR) can re-use fetch
responses from previous renders.
Learn more about the Server Components HMR Cache.
\\nWe\'ve optimized static generation to improve build times, especially for pages with slow network requests.
\\nPreviously, our static optimization process rendered pages twice—once to generate data for client-side navigation and a second time to render the HTML for the initial page visit. Now, we reuse the first render, cutting out the second pass, reducing workload and build times.
\\nAdditionally, static generation workers now share the fetch
cache across pages. If a fetch
call doesn\'t opt out of caching, its results are reused by other pages handled by the same worker. This reduces the number of requests for the same data.
We\'ve added experimental support for more control over the static generation process for advanced use cases that would benefit from greater control.
\\nWe recommend sticking to the current defaults unless you have specific requirements as these options can lead to increased resource usage and potential out-of-memory errors due to increased concurrency.
\\nconst nextConfig = {\\n experimental: {\\n // how many times Next.js will retry failed page generation attempts\\n // before failing the build\\n staticGenerationRetryCount: 1\\n // how many pages will be processed per worker\\n staticGenerationMaxConcurrency: 8\\n // the minimum number of pages before spinning up a new export worker\\n staticGenerationMinPagesPerWorker: 25\\n },\\n}\\n \\nexport default nextConfig;
Learn more about the Static Generation options.
\\nsquoosh
in favor of sharp
as an optional dependency (PR)Content-Disposition
to attachment
(PR)src
has leading or trailing spaces (PR)react-server
condition to limit unrecommended React API imports (PR)@next/font
package (PR)font-family
hashing (PR)force-dynamic
will now set a no-store
default to the fetch cache (PR)swcMinify
(PR), missingSuspenseWithCSRBailout
(PR), and outputFileTracing
(PR) behavior by default and remove deprecated options.xml
extension for dynamic sitemap routes and align sitemap URLs between development and production (PR)export const runtime = \\"experimental-edge\\"
in the App Router. Users should now switch to export const runtime = \\"edge\\"
. We\'ve added a codemod to perform this (PR)revalidateTag
and revalidatePath
during render will now throw an error (PR)instrumentation.js
and middleware.js
files will now use the vendored React packages (PR)next/dynamic
: the deprecated suspense
prop has been removed and when the component is used in the App Router, it won\'t insert an empty Suspense boundary anymore (PR)worker
module condition will not be applied (PR)ssr: false
option with next/dynamic
in Server Components (PR)metadataBase
when hosted on Vercel (PR)optimizePackageImports
(PR)bundlePagesExternals
is now stable and renamed to bundlePagesRouterDependencies
serverComponentsExternalPackages
is now stable and renamed to serverExternalPackages
.env
files by default (PR)outputFileTracingRoot
, outputFileTracingIncludes
and outputFileTracingExcludes
have been upgraded from experimental and are now stable (PR)NEXT_CACHE_HANDLER_PATH
environment variable (PR)priority
attribute (PR)unstable_rethrow
function to rethrow Next.js internal errors in the App Router (PR)unstable_after
can now be used in static pages (PR)next/dynamic
component is used during SSR, the chunk will be prefetched (PR)esmExternals
option is now supported on the App Router (PR)experimental.allowDevelopmentBuild
option can be used to allow NODE_ENV=development
with next build
for debugging purposes (PR)vercel/og
updated with a memory leak fix (PR)msw
for APIs mocking (PR)To learn more, check out the upgrade guide.
\\nNext.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.\\nThis release was brought to you by:
\\nHuge thanks to @AbhiShake1, @Aerilym, @AhmedBaset, @AnaTofuZ, @Arindam200, @Arinji2, @ArnaudFavier, @ArnoldVanN, @Auxdible, @B33fb0n3, @Bhavya031, @Bjornnyborg, @BunsDev, @CannonLock, @CrutchTheClutch, @DeepakBalaraman, @DerTimonius, @Develliot, @EffectDoplera, @Ehren12, @Ethan-Arrowood, @FluxCapacitor2, @ForsakenHarmony, @Francoscopic, @Gomah, @GyoHeon, @Hemanshu-Upadhyay, @HristovCodes, @HughHzyb, @IAmKushagraSharma, @IDNK2203, @IGassmann, @ImDR, @IncognitoTGT, @Jaaneek, @JamBalaya56562, @Jeffrey-Zutt, @JohnGemstone, @JoshuaKGoldberg, @Julian-Louis, @Juneezee, @KagamiChan, @Kahitar, @KeisukeNagakawa, @KentoMoriwaki, @Kikobeats, @KonkenBonken, @Kuboczoch, @Lada496, @LichuAcu, @LorisSigrist, @Lsnsh, @Luk-z, @Luluno01, @M-YasirGhaffar, @Maaz-Ahmed007, @Manoj-M-S, @ManuLpz4, @Marukome0743, @MaxLeiter, @MehfoozurRehman, @MildTomato, @MonstraG, @N2D4, @NavidNourani, @Nayeem-XTREME, @Netail, @NilsJacobsen, @Ocheretovich, @OlyaPolya, @PapatMayuri, @PaulAsjes, @PlagueFPS, @ProchaLu, @Pyr33x, @QiuranHu, @RiskyMH, @Sam-Phillemon9493, @Sayakie, @Shruthireddy04, @SouthLink, @Strift, @SukkaW, @Teddir, @Tim-Zj, @TrevorSayre, @Unsleeping, @Willem-Jaap, @a89529294, @abdull-haseeb, @abhi12299, @acdlite, @actopas, @adcichowski, @adiguno, @agadzik, @ah100101, @akazwz, @aktoriukas, @aldosch, @alessiomaffeis, @allanchau, @alpedia0, @amannn, @amikofalvy, @anatoliik-lyft, @anay-208, @andrii-bodnar, @anku255, @ankur-dwivedi, @aralroca, @archanaagivale30, @arlyon, @atik-persei, @avdeev, @baeharam, @balazsorban44, @bangseongbeom, @begalinsaf, @bennettdams, @bewinsnw, @bgw, @blvdmitry, @bobaaaaa, @boris-szl, @bosconian-dynamics, @brekk, @brianshano, @cfrank, @chandanpasunoori, @chentsulin, @chogyejin, @chrisjstott, @christian-bromann, @codeSTACKr, @coderfin, @coltonehrman, @controversial, @coopbri, @creativoma, @crebelskydico, @crutchcorn, @darthmaim, @datner, @davidsa03, @delbaoliveira, @devjiwonchoi, @devnyxie, @dhruv-kaushik, @dineshh-m, @diogocapela, @dnhn, @domdomegg, @domin-mnd, @dvoytenko, @ebCrypto, @ekremkenter, @emmerich, @flybayer, @floriangosse, @forsakenharmony, @francoscopic, @frys, @gabrielrolfsen, @gaojude, @gdborton, @greatvivek11, @gnoff, @guisehn, @GyoHeon, @hamirmahal, @hiro0218, @hirotomoyamada, @housseindjirdeh, @hungdoansy, @huozhi, @hwangstar156, @iampoul, @ianmacartney, @icyJoseph, @ijjk, @imddc, @imranolas, @iscekic, @jantimon, @jaredhan418, @jeanmax1me, @jericopulvera, @jjm2317, @jlbovenzo, @joelhooks, @joeshub, @jonathan-ingram, @jonluca, @jontewks, @joostmeijles, @jophy-ye, @jordienr, @jordyfontoura, @kahlstrm, @karlhorky, @karlkeefer, @kartheesan05, @kdy1, @kenji-webdev, @kevva, @khawajaJunaid, @kidonng, @kiner-tang, @kippmr, @kjac, @kjugi, @kshehadeh, @kutsan, @kwonoj, @kxlow, @leerob, @lforst, @li-jia-nan, @liby, @lonr, @lorensr, @lovell, @lubieowoce, @luciancah, @luismiramirez, @lukahartwig, @lumirlumir, @luojiyin1987, @mamuso, @manovotny, @marlier, @mauroaccornero, @maxhaomh, @mayank1513, @mcnaveen, @md-rejoyan-islam, @mehmetozguldev, @mert-duzgun, @mirasayon, @mischnic, @mknichel, @mobeigi, @molebox, @mratlamwala, @mud-ali, @n-ii-ma, @n1ckoates, @nattui, @nauvalazhar, @neila-a, @neoFinch, @niketchandivade, @nisabmohd, @none23, @notomo, @notrab, @nsams, @nurullah, @okoyecharles, @omahs, @paarthmadan, @pathliving, @pavelglac, @penicillin0, @phryneas, @pkiv, @pnutmath, @qqww08, @r34son, @raeyoung-kim, @remcohaszing, @remorses, @rezamauliadi, @rishabhpoddar, @ronanru, @royalfig, @rubyisrust, @ryan-nauman, @ryohidaka, @ryota-murakami, @s-ekai, @saltcod, @samcx, @samijaber, @sean-rallycry, @sebmarkbage, @shubh73, @shuding, @sirTangale, @sleevezip, @slimbde, @soedirgo, @sokra, @sommeeeer, @sopranopillow, @souporserious, @srkirkland, @steadily-worked, @steveluscher, @stipsan, @styfle, @stylessh, @syi0808, @symant233, @tariknh, @theoludwig, @timfish, @timfuhrmann, @timneutkens, @tknickman, @todor0v, @tokkiyaa, @torresgol10, @tranvanhieu01012002, @txxxxc, @typeofweb, @unflxw, @unstubbable, @versecafe, @vicb, @vkryachko, @wbinnssmith, @webtinax, @weicheng95, @wesbos, @whatisagi, @wiesson, @woutvanderploeg, @wyattjoh, @xiaohanyu, @xixixao, @xugetsu, @yosefbeder, @ypessoa, @ytori, @yunsii, @yurivangeffen, @z0n, @zce, @zhawtof, @zsh77, and @ztanner for helping!
","description":"Next.js 15 is officially stable and ready for production. This release builds on the updates from both RC1 and RC2. We\'ve focused heavily on stability while adding some exciting updates we think you\'ll love. Try Next.js 15 today: terminal\\n# Use the new automated upgrade CLI\\nnpx @n…","guid":"https://nextjs.org/blog/next-15","author":null,"authorUrl":null,"authorAvatar":null,"publishedAt":"2024-10-24T18:55:48.105Z","media":[{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Fnext-15-rc%2Fhydration-error-before-light.png&w=2048&q=75&dpl=dpl_5XThn1PdhcUknyqm5UfWvWFgaTgD","type":"photo","width":962,"height":517},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Fnext-15-rc%2Fhydration-error-before-dark.png&w=2048&q=75&dpl=dpl_5XThn1PdhcUknyqm5UfWvWFgaTgD","type":"photo","width":962,"height":517},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Fnext-15-rc%2Fhydration-error-after-light.png&w=1920&q=75&dpl=dpl_5XThn1PdhcUknyqm5UfWvWFgaTgD","type":"photo","width":960,"height":654},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Fnext-15-rc%2Fhydration-error-after-dark.png&w=1920&q=75&dpl=dpl_5XThn1PdhcUknyqm5UfWvWFgaTgD","type":"photo","width":960,"height":654},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Fnext-15-rc2%2Fstatic-route-light.png&w=3840&q=75&dpl=dpl_5XThn1PdhcUknyqm5UfWvWFgaTgD","type":"photo","width":1720,"height":516},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Fnext-15-rc2%2Fstatic-route-dark.png&w=3840&q=75&dpl=dpl_5XThn1PdhcUknyqm5UfWvWFgaTgD","type":"photo","width":1720,"height":516}],"categories":null,"attachments":null,"extra":null,"language":null},{"title":"Turbopack Dev is Now Stable","url":"https://nextjs.org/blog/turbopack-for-development-stable","content":"It\'s been a long road, but we are happy to announce that next dev --turbo
is now stable and ready to speed up your development experience. We\'ve been using it to iterate on vercel.com, nextjs.org, v0, and all of our other applications with great results.
Since its release 8 years ago, Next.js has been used to build everything, from weekend hobby projects to sophisticated enterprise applications. When Next.js was first released, webpack was clearly the best choice for the framework\'s bundling foundation, but over time it has struggled to keep up with the needs of modern web developers. Our community started to find it painfully slow to iterate while waiting for routes to load, code changes to reflect, and production builds to deploy.
\\nWe invested a lot of time and effort optimizing webpack, but at a certain point, we felt we weren\'t getting enough improvement for the effort involved. We needed a new foundation that could support the many Next.js applications already in production today, as well as the future innovations we had planned, like React Server Components.
\\nThese were our requirements for this new bundler:
\\nWe evaluated all existing solutions at the time and found that each one had trade-offs that didn\'t align with our requirements and goals. It made sense for us to design something from the ground up that could accomplish exactly what Next.js needs today and own the roadmap so we can build and experiment with what it will need tomorrow. This was our motivation to create Turbopack.
\\nWe started out by optimizing the development experience, and that\'s what we\'re releasing as stable today. We\'ve been extensively dogfooding Turbopack with Vercel\'s applications, and have noticeably improved the iteration velocity of our developers. For example, with vercel.com
, a large Next.js app, we\'ve seen:
In this post, we\'ll discuss how we achieved these results, along with some other highlights. We\'ll also clarify exactly what to expect from this release and provide a roadmap for what to expect next.
\\nOne of the biggest issues we were hearing from our community was that routes were taking too long to load in development, which came down to webpack\'s compilation speed. Next.js compiles routes on-demand to avoid having to compile all possible routes before they are needed, which keeps the initial startup fast and memory usage lower, but even then, you could still find yourself tapping your feet while waiting for a single page to load.
\\nTo be fair, bundlers like webpack are doing a lot underneath the hood. When compiling a route for the first time, the bundler starts at an “entrypoint”. In the case of Next.js, it\'s a combination of page.tsx
and all related files for that route, like layout.tsx
and loading.tsx
, etc. These entrypoints are parsed to find import
statements that get resolved to files, which then get processed the same as the entrypoints, and this cycle continues until no more imports are found. This process builds a graph of modules, which can be made up of not just TypeScript / JavaScript modules (including node_modules
), but also CSS files (both global and CSS modules), and static files like imported images for next/image
.
After all modules are collected, the module graph is used to create bundles of JavaScript, often referred to as “chunks.” These chunks are the outputs of the compiler that run on the server (at build-time or runtime) or in the browser.
\\nwebpack does not support creating graphs that produce outputs for multiple environments, so we have to run at least two separate compilers in Next.js with webpack today, one for the server and one for the browser. We must compile the server module graph first so that all references to \\"use client\\"
can be found. Once the server is built, we traverse its graph to create the relevant entrypoints for the browser compiler. Since this is a separate webpack compiler, there\'s some overhead in this process, like parsing the same code twice across client and server.
With Turbopack, we set out to remove the overhead of running multiple compilers and coordinating between them. The solution was to make the compiler aware of multiple different output targets. Internally, these are called target “transitions”. We can mark an import as a transition from server to browser or from browser to server. This is what allows Turbopack to efficiently bundle Server Components and Client Components, as well as Server Functions imported from Client Components.
\\nIn addition to improving performance, having a single compiler that can handle multiple environments in a single pass has reliability and debugging benefits, as we no longer have to coordinate between two separate compiler processes in Next.js.
\\nAnother big difference between webpack and Turbopack is that Turbopack can parallelize work across multiple CPUs, whereas with webpack, only the TypeScript / JavaScript transformation step using SWC is parallelized.
\\nwebpack doesn\'t support parallelizing across CPUs because, in order to parallelize effectively, data must be easily accessible across threads. webpack was built in a way that heavily uses large JavaScript objects, which can\'t be shared across threads easily without expensive serialization and deserialization. This overhead often negates the performance improvement of leveraging multiple CPUs. Turbopack is written in Rust, which does not have the same limitations, and was built with parallelization in mind from the start.
\\nWe were also able to achieve performance wins with faster filesystem reads and writes, faster module resolution, and by skipping more work on side-effect free modules.
\\nWhen using Turbopack on vercel.com
, a large Next.js application, we\'ve seen up to 45.8% faster initial compilation compared to Next.js with webpack.
Fast Refresh is the system that bundlers use to propagate changes to the route you\'re currently looking at in the browser, sometimes referred to as Hot Module Replacement (HMR).
\\nNext.js has a deeper integration that connects Fast Refresh to React, making sure that React doesn\'t lose state whenever you change a component.
\\nWith webpack, we found there is a limit to the performance of Fast Refresh when you hit a certain number of JavaScript modules. Webpack needs to do graph traversal and generate outputs even for modules that have not changed, scaling linearly with the amount of JavaScript modules.
\\nWe found that at around 30,000 modules, code changes consistently have at least 1 second of overhead to process an update, regardless of whether the change is small. For example, changing a color in a CSS file could take 1 second to show up on screen.
\\nThis performance was not acceptable for us. We believe that incremental builds should scale with only the size of local changes, not the size of the route or application. When button.tsx
changes, the compiler should only have to run the work related to that file change instead of having to recompute other modules and output files that are not affected by the change. To combat this, we prioritized a foundation in Turbopack that allows very granular recomputing of work.
This effort turned into the underlying library, Turbo Engine, which uses an automatic demand-driven incremental computation architecture to provide interactive hot-reloading of massive Next.js and React applications in tens of milliseconds. This architecture is based on over a decade of research and prior art, including webpack, Salsa, Parcel, Adapton, and the Rust compiler\'s query system.
\\nNow with Turbopack, Fast Refresh speed scales with the size of your changes, which is how we\'ve been able to achieve 96.3% faster code updates with Fast Refresh on large Next.js apps like vercel.com.
\\nAs Next.js has grown in adoption over the years, we\'ve found it increasingly hard to reproduce reported issues on GitHub, especially related to compiler performance and memory usage. This is because most people can\'t share their application code, or when they share the code, the application can\'t run because it requires a database or other setup.
\\nTo begin to address this, we added tracing to the internals of Next.js. These traces are written to a file in the .next
folder and do not include application code — only the file path, the time the compiler took on it, and other timings like individual transforms. However, with webpack, we never had a good way to clearly distinguish memory usage of the compiler from memory usage of framework or application code, as they all run in the same Node.js instance.
With Turbopack, we were able to design with instrumentation from the beginning. We implemented an instrumentation layer in Turbo Engine that allows for collecting timings of each individual function. We were able to extend these traces to also keep track of the memory allocation, deallocation, and persisted memory across every function.
\\nThis new, advanced tracing gives us all the information needed to investigate slowdowns and memory usage deeply; it only requires a trace instead of a full codebase.
\\nIn order to process these new traces, we\'ve implemented a custom trace viewer that stays performant regardless of application and trace size. It\'s a trace viewer specifically built for investigating slowdowns and memory usage for Turbopack and has allowed us to optimize performance across many early adopter applications as it shortens the feedback loop.
\\nWhile the trace viewer was initially built for internal usage (and it\'s intended for situations where a deep technical dive is needed), we\'ve landed the required pieces to run it yourself in Next.js. You can generate a Turbopack trace using these instructions. Then, when the trace is generated, you can use next internal turbo-trace-server .next/trace-turbopack
to start the server that allows for inspecting the trace. There is a quick video overview of the trace viewer available here.
When using Next.js with webpack, compile times are often not transparent enough. In one case, it may take 10 seconds to open a page, and in another, it may take 20 seconds. While a cache may be present, it sometimes doesn\'t have enough impact to produce consistent results. Even on compilation without caches, we\'ve seen some variance.
\\nThe underlying architecture of Turbopack ensures variance in compile times is much more consistent. The compile times for routes only vary a few percent, allowing us to consistently optimize the compiler performance.
\\nIn order to optimize for compilation speed with webpack, we had to accept some trade-offs that resulted in divergent development and production environments. Some examples of those trade-offs are that we use style-loader
, which injects the style into the page and allows for Fast Refreshing them, without reloading the page. However, this means that the styles are injected by JavaScript in development, which causes a flash of unstyled content. We work around this flash of unstyled content, so you don\'t see it. Another example is that Next.js with webpack uses eval-source-map
, meaning that all code is wrapped in eval
and the sourcemaps are included in that, which ensures sourcemaps are available in development at the expense of the bundled code being harder to inspect and debug. While webpack supports outputting full sourcemaps using the source-map
option, it causes an outsized impact on compilation time and memory usage.
For Turbopack, we set out to solve these by default, outputting CSS files and sourcemaps without using eval
. Turbopack leverages sections
sourcemaps, a relatively new part of the source-map specification that allows for more efficient merging of sourcemaps outputs. Where we previously had to generate all mappings in one place, we\'re now able to generate and cache them much more granularly.
The CSS handling in Turbopack always outputs CSS files, and similar to JavaScript handling it can update the CSS file without refreshing the browser by a mechanism that is part of the Turbopack development runtime.
\\nWe can now confidently say that when something works in development with Turbopack, it also works and behaves the same in production.
\\nTwo years ago, we introduced Turbopack as an alpha with Next.js 13, offering a preview of its performance potential. While initial results were promising, it only supported basic usage—many Next.js features, like basePath
, weren\'t yet implemented.
Over the following year, we focused on adding missing Next.js and bundling features. Based on community feedback, we decided to fully focus on the next dev
experience so we could address the most common iteration velocity complaints. By last year\'s Next.js Conf, 90% of development tests were passing, and Vercel developers were already using Turbopack in day-to-day development.
In April, we announced Next.js 14.2 with 99.8% of tests passing, reaching 100% soon after. Since then, we\'ve addressed GitHub-reported issues, especially around npm packages, Fast Refresh, and error location accuracy.
\\nAdmittedly, the road to stability has taken a long time, but that mostly comes down to Next.js\'s extensive test suite, which sets a high bar for stability. We\'ve had 8 years to uncover edge cases and add 6,599 development tests that also needed to pass with Turbopack. An additional factor is that we designed Turbopack with a completely different architecture than webpack. Simply porting webpack to Rust would have been easier but wouldn\'t have unlocked the performance wins we want to achieve.
\\nNow that Turbopack passes all tests, has been validated with top npm packages, and feedback from early adopters is addressed, we\'re ready to stamp it as stable.
\\nThis has been a point of confusion in the past, so we\'ll take this section to clarify what this release unlocks for the Next.js community.
\\nThis release specifically marks the next dev --turbo
command as stable. Production builds (next build --turbo
) are not supported yet, but keep reading for an update as they are in progress. We eventually plan to release a standalone version of Turbopack outside of Next.js, but we want to prove its merit by enhancing the Next.js community\'s experience first.
Other than the unsupported features we will cover in the next section, Turbopack should work with all stable features of Next.js. For clarity, Turbopack supports both App Router and Pages Router. Experimental features may or may not work with Turbopack, but they certainly will by the time they are marked stable.
\\nIf your application has webpack customization but only adds webpack loaders, you might be able to already use Turbopack by configuring the loaders for Turbopack. You can read the documentation for webpack loader support in Turbopack.
\\nHere\'s a list of webpack loaders that are verified to work with Turbopack:
\\n@svgr/webpack
babel-loader
url-loader
file-loader
raw-loader
tsconfig-paths-webpack-plugin
— supported out of the box, no plugin needed.Most CSS and CSS-in-JS libraries are supported:
\\ndata:
attributes — We\'re going to look into supporting StyleX after next build --turbo
is stable.We want to call out that the performance of the version released today is significantly better than that of the webpack, but it is not the final performance number. We\'ve been following Kent Beck\'s famous formula of “Make it work. Make it good. Make it fast.\\" So far, a large portion of our effort has gone towards the “Make it work” stage since we have to catch up to the scope of Next.js and webpack, which have matured for close to a decade.
\\nTurbopack is betting heavily on its caching infrastructure, but as you may know, caching is one of the only two hard things in software development. From experience, we knew that adding caching to an architecture that wasn\'t explicitly built for it can lead to undesirable results, so we enabled caching for even the most granular functions. This means that rebuilds are extremely fast at the cost of cold builds and memory usage, and we are working towards a better balance. The neat thing is that we can use our advanced tracing mentioned earlier in the post to find inefficiencies and profile which functions are most worthwhile to cache.
\\nOver the past 3 months, we\'ve already made some significant improvements. Comparing Turbopack in Next.js 15 RC 2 versus Turbopack in 15 RC 1 shows the results of these optimizations:
\\nThe stable version of Turbopack contains an in-memory cache that must be rebuilt on every restart of the development server, which can take ten or more seconds for large applications. Something we\'re extremely excited about are the big wins we\'re seeing when testing on-disk persistent caching, which we will cover later in this post.
\\nA huge motivation for building our own bundler was the need to match the existing behaviors of webpack as much as possible, which is something we couldn\'t guarantee with any existing solution at the time. This includes the way files are resolved and smaller features of webpack, such as the webpackIgnore
comment that some npm packages use.
Unfortunately, we did have to remove some features in order to future-proof Turbopack and the related Next.js implementation. Those features will still be supported when you use webpack.
\\nThere are a few highlights, let\'s dig into the reasons why we had to change them:
\\nwebpack()
configuration is not supported. Turbopack is not webpack, it doesn\'t have the same configuration option structure, though it does support many of the same features. Specifically we have implemented support for webpack loaders and resolve aliases. Most webpack loaders that are transforming code are supported out of the box. Some webpack loaders that do exotic things, like a webpack child compiler and emitting files, are not supported.
.babelrc
will not automatically transform code. Turbopack leverages SWC by default. You\'re still able to add babel-loader
as needed, but we\'re ensuring the defaults are always fast and that these make sense in terms of architecture too. We always have to run SWC, even if you configure .babelrc
, in order to process other optimizations. This is similar to how webpack always has to run the acorn
parser to do further optimizations. If you use SWC instead of Babel with Turbopack, we can parse once and leverage the same abstract syntax tree (AST) end-to-end throughout Turbopack.
Some lesser-used CSS Modules features. We\'ve switched the processing of CSS from PostCSS to Lightning CSS. Lightning CSS is a significantly faster CSS compiler that supports CSS transformations, minification, and CSS Modules out of the box. The trade-off is that some lesser-used features are not supported. Specifically :global
and :local
pseudo selectors (their function variant :global()
and :local()
still work), @value
, and :import / :export
ICSS rules. It\'s also a bit stricter than other CSS parsers and will point to errors in code rather than ignore them.
In the process of adding Lightning CSS we\'ve contributed back to the project. For example, we implemented granular options for CSS Modules to disable CSS grid prefixing and the pure
mode for CSS Modules. This makes it easier to adopt Lightning CSS for CSS Modules when coming from css-loader in webpack. We have also improved errors for the unsupported CSS Modules features.
We are thankful to Devon Govett, the author and maintainer of Lightning CSS, for the continued collaboration on the project.
\\nExperimental features. As we are focused on Turbopack\'s stability in Next.js, we\'ve decided to focus on the stable features that are available in Next.js first.
\\nFor the full list, see the documentation page.
\\nTurbopack has come a long way, but there\'s still a lot of work to be done. The two exciting features coming down the pipeline are persistent caching and production builds. We expect the rollout to look something like the following order:
\\nWhile webpack will stay in Next.js, we\'re expecting that because of the benefits of Turbopack, the majority of Next.js applications will want to use it. Once Turbopack for production builds is complete we\'ll start work to support commonly used webpack plugins.
\\nWe have loose plans for Turbopack beyond that, but we\'d like to keep this post constrained to what we can confidently ship in the foreseeable future. We may only be talking about two features, but there\'s a lot that goes into them, so it\'s worth diving into.
\\nPersistent caching means storing the work done by the compiler in a way that allows it to be reused across restarts of the development server or across multiple production builds.
\\nIn short, Turbopack avoids redoing the same work, even if you restart.
\\nAs mentioned in the Faster Fast Refresh section, we built Turbo Engine to ensure work can be parallelized and cached, so that whenever you make a file change, we only have to run the work related to that file change. What if we could give you this experience across restarts and when opening a route? We wouldn\'t have to redo compilation work that was already done in a previous development session. What if we could get the benefits of Fast Refresh but for opening routes compiled in previous development sessions and across multiple builds with the next build
?
That\'s exactly what we\'ve been working on: a new storage layer for Turbo Engine that supports persisting the compilation work to disk and restoring it when starting the development server or building again.
\\nWhile webpack does have disk caching enabled by default in Next.js, it has quite a few limitations. It\'s notable that a large portion of the cache has to be restored from disk and read into memory in order to function. It never quite felt like there is a granular enough cache. For example, on larger applications at Vercel, we found that the webpack disk cache could even be slower than doing all the work from scratch when the cache had grown to a sufficiently large size.
\\nUnlike the existing disk caching with webpack, the persistent cache with Turbopack truly feels like Fast Refresh across restarts. Routes that take over 10 seconds to compile the very first time take less than 500ms to restore from cache once they\'ve been compiled once.
\\nWe have seen similar results for next build
with Turbopack, where only the changed files are recompiled, and everything else stays as-is. In the multiple steps that next build
takes, this moves the majority of time spent from running compilation and bundling to running TypeScript type checking.
The persistent caching is currently a work in progress, as we want to verify it using our internal Next.js applications first. The initial results are very promising, and performance will get even better over time as we keep optimizing these hot paths.
\\nOnce the persistent cache is stable, it will be enabled by default. Enabling persistent caching will not require changes to your codebase.
\\nIf you are interested in testing out persistent caching, please reach out!
\\nWe\'re excited to share that we\'re making substantial progress towards stable production builds with Turbopack. Currently, 96% of our production tests are passing, which is a big step forward. However, there are still areas that need more work before we can confidently recommend Turbopack for production at scale.
\\nProduction builds bring their own unique challenges compared to development, and we\'re actively working to address them. Below, we\'ll go over what\'s already been optimized and what\'s still in progress.
\\nEnsuring correctness is essential for reliable production builds. Here\'s the current status:
\\nUX Performance is key to delivering fast load times and efficient resource usage. Here\'s what we\'re working on:
\\nnext/dynamic
.export { foo as \\"string name\\" }
.We\'re thrilled to confidently recommend the next dev --turbo
, and we can\'t wait to hear how it improves your development experience. Give it a try today and see the performance gains for yourself.
This is just the beginning—persistent caching and production builds are on the horizon, which will bring even more speed and reliability to your workflow.
\\nWe\'ll share more updates as we progress towards ensuring correctness and optimizing performance to handle even the largest applications seamlessly. Stay tuned for future releases and improvements as we work towards making Turbopack the best solution for both development and production builds.
\\nWe are thankful to the thousands of developers who participated in testing, reporting issues, and verifying fixes throughout the Turbopack beta and release candidate phases.
\\nThis release was brought to you by:
\\nReact Server Components (RSC) in App Router is a novel paradigm that eliminates much of the redundancy and potential risks linked with conventional methods. Given the newness, developers and subsequently security teams may find it challenging to align their existing security protocols with this model.
\\nThis document is meant to highlight a few areas to look out for, what protections are built-in, and include a guide for auditing applications. We focus especially on the risks of accidental data exposure.
\\nReact Server Components blur the line between server and client. Data handling is paramount in understanding where information is processed and subsequently made available.
\\nThe first thing we need to do is pick what data handling approach is appropriate for our project.
\\nWe recommend that you stick to one approach and don\'t mix and match too much. This makes it clear for both developers working in your code base and security auditors for what to expect. Exceptions pop out as suspicious.
\\nIf you\'re adopting Server Components in an existing project, the recommended approach is to handle Server Components at runtime as unsafe/untrusted by default like SSR or within the client. So there is no assumption of an internal network or zones of trust and engineers can apply the concept of Zero Trust. Instead, you only call custom API endpoints such as REST or GraphQL using fetch()
from Server Components just like if it was executing on the client. Passing along any cookies.
If you had existing getStaticProps
/getServerSideProps
connecting to a database, you might want to consolidate the model and move these to API end points as well so you have one way to do things.
Look out for any access control that assumes fetches from the internal network are safe.
\\nThis approach lets you keep existing organizational structures where existing backend teams, specialized in security can apply existing security practices. If those teams use languages other than JavaScript, that works well in this approach.
\\nIt still takes advantage of many of the benefits of Server Components by sending less code to the client and inherent data waterfalls can execute with low latency.
\\nOur recommended approach for new projects is to create a separate Data Access Layer inside your JavaScript codebase and consolidate all data access in there. This approach ensures consistent data access and reducing the chance of authorization bugs occurring. It\'s also easier to maintain given you\'re consolidating into a single library. Possibly providing better team cohesion with a single programming language. You also get to take advantage of better performance with lower runtime overhead, the ability to share an in-memory cache across different parts of a request.
\\nYou build an internal JavaScript library that provides custom data access checks before giving it to the caller. Similar to HTTP endpoints but in the same memory model. Every API should accept the current user and check if the user can see this data before returning it. The principle is that a Server Component function body should only see data that the current user issuing the request is authorized to have access to.
\\nFrom this point, normal security practices for implementing APIs take over.
\\nimport { cache } from \'react\';\\nimport { cookies } from \'next/headers\';\\n \\n// Cached helper methods makes it easy to get the same value in many places\\n// without manually passing it around. This discourages passing it from Server\\n// Component to Server Component which minimizes risk of passing it to a Client\\n// Component.\\nexport const getCurrentUser = cache(async () => {\\n const token = cookies().get(\'AUTH_TOKEN\');\\n const decodedToken = await decryptAndValidate(token);\\n // Don\'t include secret tokens or private information as public fields.\\n // Use classes to avoid accidentally passing the whole object to the client.\\n return new User(decodedToken.id);\\n});
import \'server-only\';\\nimport { getCurrentUser } from \'./auth\';\\n \\nfunction canSeeUsername(viewer: User) {\\n // Public info for now, but can change\\n return true;\\n}\\n \\nfunction canSeePhoneNumber(viewer: User, team: string) {\\n // Privacy rules\\n return viewer.isAdmin || team === viewer.team;\\n}\\n \\nexport async function getProfileDTO(slug: string) {\\n // Don\'t pass values, read back cached values, also solves context and easier to make it lazy\\n \\n // use a database API that supports safe templating of queries\\n const [rows] = await sql`SELECT * FROM user WHERE slug = ${slug}`;\\n const userData = rows[0];\\n \\n const currentUser = await getCurrentUser();\\n \\n // only return the data relevant for this query and not everything\\n // <https://www.w3.org/2001/tag/doc/APIMinimization>\\n return {\\n username: canSeeUsername(currentUser) ? userData.username : null,\\n phonenumber: canSeePhoneNumber(currentUser, userData.team)\\n ? userData.phonenumber\\n : null,\\n };\\n}
These methods should expose objects that are safe to be transferred to the client as is. We like to call these Data Transfer Objects (DTO) to clarify that they\'re ready to be consumed by the client.
\\nThey might only get consumed by Server Components in practice. This creates a layering where security audits can focus primarily on the Data Access Layer while the UI can rapidly iterate. Smaller surface area and less code to cover makes it easier to catch security issues.
\\nimport {getProfile} from \'../../data/user\'\\nexport async function Page({ params: { slug } }) {\\n // This page can now safely pass around this profile knowing\\n // that it shouldn\'t contain anything sensitive.\\n const profile = await getProfile(slug);\\n ...\\n}
Secret keys can be stored in environment variables but only the data access layer should access process.env
in this approach.
Another approach is to just put your database queries directly in your Server Components. This approach is only appropriate for rapid iteration and prototyping. E.g. for a small product with a small team where everyone is aware of the risks and how to watch for them.
\\nIn this approach you\'ll want to audit your \\"use client\\"
files carefully. While auditing and reviewing PRs, look at all the exported functions and if the type signature accepts overly broad objects like User
, or contains props like token
or creditCard
. Even privacy sensitive fields like phoneNumber
need extra scrutiny. A Client Component should not accept more data than the minimal data it needs to perform its job.
import Profile from \'./components/profile.tsx\';\\n \\nexport async function Page({ params: { slug } }) {\\n const [rows] = await sql`SELECT * FROM user WHERE slug = ${slug}`;\\n const userData = rows[0];\\n // EXPOSED: This exposes all the fields in userData to the client because\\n // we are passing the data from the Server Component to the Client.\\n // This is similar to returning `userData` in `getServerSideProps`\\n return <Profile user={userData} />;\\n}
\'use client\';\\n// BAD: This is a bad props interface because it accepts way more data than the\\n// Client Component needs and it encourages server components to pass all that\\n// data down. A better solution would be to accept a limited object with just\\n// the fields necessary for rendering the profile.\\nexport default async function Profile({ user }: { user: User }) {\\n return (\\n <div>\\n <h1>{user.name}</h1>\\n ...\\n </div>\\n );\\n}
Always use parameterized queries, or a db library that does it for you, to avoid SQL injection attacks.
\\nCode that should only ever execute on the server can be marked with:
\\nimport \'server-only\';
This will cause the build to error if a Client Component tries to import this module. This can be used to ensure that proprietary/sensitive code or internal business logic doesn\'t accidentally leak to the client.
\\nThe primary way to transfer data is using the React Server Components protocol which happens automatically when passing props to the Client Components. This serialization supports a superset of JSON. Transferring custom classes is not supported and will result in an error.
\\nTherefore, a nice trick to avoid too large objects being accidentally exposed to the client is to use class
for your data access records.
In the upcoming Next.js 14 release, you can also try out the experimental React Taint APIs by enable the taint
flag in next.config.js
.
module.exports = {\\n experimental: {\\n taint: true,\\n },\\n};
This lets you mark an object that should not be allowed to be passed to the client as is.
\\nimport { experimental_taintObjectReference } from \'react\';\\n \\nexport async function getUserData(id) {\\n const data = ...;\\n experimental_taintObjectReference(\\n \'Do not pass user data to the client\',\\n data\\n );\\n return data;\\n}
import { getUserData } from \'./data\';\\n \\nexport async function Page({ searchParams }) {\\n const userData = getUserData(searchParams.id);\\n return <ClientComponent user={userData} />; // error\\n}
This does not protect against extracting data fields out of this object and passing them along:
\\nexport async function Page({ searchParams }) {\\n const { name, phone } = getUserData(searchParams.id);\\n // Intentionally exposing personal data\\n return <ClientComponent name={name} phoneNumber={phone} />;\\n}
For unique strings such as tokens, the raw value can be blocked as well using taintUniqueValue
.
import { experimental_taintObjectReference, experimental_taintUniqueValue } from \'react\';\\n \\nexport async function getUserData(id) {\\n const data = ...;\\n experimental_taintObjectReference(\\n \'Do not pass user data to the client\',\\n data\\n );\\n experimental_taintUniqueValue(\\n \'Do not pass tokens to the client\',\\n data,\\n data.token\\n );\\n return data;\\n}
However, even this doesn\'t block derived values.
\\nIt\'s better to avoid data getting into the Server Components in the first place - using a Data Access Layer. Taint checking provides an additional layer of protection against mistakes by specifying the value, please be mindful that functions and classes are already blocked from being passed to Client Components. More layers the minimize risk of something slipping through.
\\nBy default, environment variables are only available on the Server. By convention, Next.js also exposes any environment variable prefixed with NEXT_PUBLIC_
to the client. This lets you expose certain explicit configuration that should be available to the client.
For initial load Next.js will run both the Server Components and the Client Components on the server to produce HTML.
\\nServer Components (RSC) execute in a separate module system from the Client Components to avoid accidentally exposing information between the two modules.
\\nClient Components that render through Server-side Rendering (SSR) should be considered as the same security policy as the browser client. It should not gain access to any privileged data or private APIs. It\'s highly discouraged to use hacks to try to circumvent this protection (such as stashing data on the global object). The principle is that this code should be able to execute the same on the server as the client. In alignment with secure by default practices, Next.js will fail the build if server-only
modules are imported from a Client Component.
In Next.js App Router, reading data from a database or API is implemented by rendering Server Component pages.
\\nThe input to pages are searchParams in the URL, dynamic params mapped from the URL and headers. These can be abused to be different values by the Client. They should not be trusted and needs to be re-verified each time they are read. E.g. a searchParam should not be used to track things like ?isAdmin=true
. Just because the user is on /[team]/
doesn\'t mean that they have access to that team, that needs to be verified when reading data. The principle is to always re-read access control and cookies()
whenever reading data. Don\'t pass it as props or params.
Rendering a Server Component should never perform side-effects like mutations. This is not unique to Server Components. React naturally discourages side-effects even when rendering Client Components (outside useEffect), by doing things like double-rendering.
\\nAdditionally, in Next.js there\'s no way to set cookies or trigger revalidation of caches during rendering. This also discourages the use of renders for mutations.
\\nE.g. searchParams
should not be used to perform side-effects like saving changes or logging out. Server Actions should be used for this instead.
This means that the Next.js model never uses GET requests for side-effects when used as intended. This helps avoid a large source of CSRF issues.
\\nNext.js does have support for Custom Route Handlers (route.tsx
), which can set cookies on GET. It\'s considered an escape hatch and not part of the general model. These have to explicitly opt-in to accepting GET requests. There\'s no catch-all handler that might accidentally receive GET requests. If you do decide to create a custom GET handler, these might need extra auditing.
The idiomatic way to perform writes or mutations in Next.js App Router is using Server Actions.
\\n\'use server\';\\n \\nexport function logout() {\\n cookies().delete(\'AUTH_TOKEN\');\\n}
The \\"use server\\"
annotation exposes an end point that makes all exported functions invokable by the client. The identifiers is currently a hash of the source code location. As long as a user gets the handle to the id of an action, it can invoke it with any arguments.
As a result, those functions should always start by validating that the current user is allowed to invoke this action. Functions should also validate the integrity of each argument. This can be done manually or with a tool like zod
.
\\"use server\\";\\n \\nexport async function deletePost(id: number) {\\n if (typeof id !== \'number\') {\\n // The TypeScript annotations are not enforced so\\n // we might need to check that the id is what we\\n // think it is.\\n throw new Error();\\n }\\n const user = await getCurrentUser();\\n if (!canDeletePost(user, id)) {\\n throw new Error();\\n }\\n ...\\n}
Server Actions can also be encoded in closures. This lets the action be associated with a snapshot of data used at the time of rendering so that you can use this when the action is invoked:
\\nexport default function Page() {\\n const publishVersion = await getLatestVersion();\\n async function publish() {\\n \\"use server\\";\\n if (publishVersion !== await getLatestVersion()) {\\n throw new Error(\'The version has changed since pressing publish\');\\n }\\n ...\\n }\\n return <button action={publish}>Publish</button>;\\n}\\n
The snapshot of the closure must be sent to the client and back when the server is invoked.
\\nIn Next.js 14, the closed over variables are encrypted with the action ID before sent to the client. By default a private key is generated automatically during the build of a Next.js project. Each rebuild generates a new private key which means that each Server Action can only be invoked for a specific build. You might want to use Skew Protection to ensure that you always invoke the correction version during redeploys.
\\nIf you need a key that rotates more frequently or is persistent across multiple builds, you can configure it manually using NEXT_SERVER_ACTIONS_ENCRYPTION_KEY
environment variable.
By encrypting all closed over variables, you don\'t accidentally expose any secrets in them. By signing it, it makes it harder for an attacker to mess with the input to the action.
\\nAnother alternative to using closures is to use the .bind(...)
function in JavaScript. These are NOT encrypted. This provides an opt-out for performance and is also consistent with .bind()
on the client.
async function deletePost(id: number) {\\n \\"use server\\";\\n // verify id and that you can still delete it\\n ...\\n}\\n \\nexport async function Page({ slug }) {\\n const post = await getPost(slug);\\n return <button action={deletePost.bind(null, post.id)}>\\n Delete\\n </button>;\\n}
The principle is that the argument list to Server Actions (\\"use server\\"
) must always be treated as hostile and the input has to be verified.
All Server Actions can be invoked by plain <form>
, which could open them up to CSRF attacks. Behind the scenes, Server Actions are always implemented using POST and only this HTTP method is allowed to invoke them. This alone prevents most CSRF vulnerabilities in modern browsers, particularly due to Same-Site cookies being the default.
As an additional protection Server Actions in Next.js 14 also compares the Origin
header to the Host
header (or X-Forwarded-Host
). If they don\'t match, the Action will be rejected. In other words, Server Actions can only be invoked on the same host as the page that hosts it. Very old unsupported and outdated browsers that don\'t support the Origin
header could be at risk.
Server Actions doesn\'t use CSRF tokens, therefore HTML sanitization is crucial.
\\nWhen Custom Route Handlers (route.tsx
) are used instead, extra auditing can be necessary since CSRF protection has to be done manually there. The traditional rules apply there.
Bugs happen. When errors are thrown on the Server they are eventually rethrown in Client code to be handled in the UI. The error messages and stack traces might end up containing sensitive information. E.g. [credit card number] is not a valid phone number
.
In production mode, React doesn\'t emit errors or rejected promises to the client. Instead a hash is sent representing the error. This hash can be used to associate multiple of the same errors together and associate the error with server logs. React replaces the error message with its own generic one.
\\nIn development mode, server errors are still sent in plain text to the client to help with debugging.
\\nIt\'s important to always run in Next.js in production mode for production workloads. Development mode does not optimize for security and performance.
\\nCustom Route Handlers and Middleware are considered low level escape hatches for features that cannot be implemented using any other built-in functionality. This also opens up potential footguns that the framework otherwise protects against. With great power comes great responsibility.
\\nAs mentioned above, route.tsx
routes can implement custom GET and POST handlers which may suffer from CSRF issues if not done correctly.
Middleware can be used to limit access to certain pages. Usually it\'s best to do this with an allow list rather than a deny list. That\'s because it can be tricky to know all the different ways there is to get access to data, such as if there\'s a rewrite or client request.
\\nFor example, it\'s common to only think about the HTML page. Next.js also supports client navigation that can load RSC/JSON payloads. In Pages Router, this used to be in a custom URL.
\\nTo make writing matchers easier Next.js App Router always uses the page\'s plain URL for both initial HTML, client navigations and Server Actions. Client navigations use ?_rsc=...
search param as a cache breaker.
Server Actions live on the page they\'re used on and as such inherit the same access control. If Middleware allows reading a page, you can also invoke actions on that page. To limit access to Server Actions on a page, you can ban the POST HTTP method on that page.
\\nIf you\'re doing an audit of a Next.js App Router project here are a few things we recommend looking extra at:
\\n\\"use client\\"
files. Are the Component props expecting private data? Are the type signatures overly broad?\\"use server\\"
files. Are the Action arguments validated in the action or inside the Data Access Layer? Is the user re-authorized inside the action?/[param]/
. Folders with brackets are user input. Are params validated?middleware.tsx
and route.tsx
have a lot of power. Spend extra time auditing these using traditional techniques. Perform Penetration Testing or Vulnerability Scanning regularly or in alignment with your team\'s software development lifecycle.This RFC (Request for Comment) outlines the biggest update to Next.js since it was introduced in 2016:
\\nThe new Next.js router will be built on top of the recently released React 18 features. We plan to introduce defaults and conventions that allow you to easily adopt these new features and take advantage of the benefits they unlock.
\\n\\n\\nWork on this RFC is ongoing and we\'ll announce when the new features are available. To provide feedback, join the conversation on Github Discussions.
\\n
app
DirectoryWe\'ve been gathering community feedback from GitHub, Discord, Reddit, and our developer survey about the current limitations of routing in Next.js. We\'ve found that:
\\nWhile the current routing system has worked well since the beginning of Next.js, we want to make it easier for developers to build more performant and feature-rich web applications.
\\nAs framework maintainers, we also want to build a routing system that is backwards compatible and aligns with the future of React.
\\n\\n\\nNote: Some routing conventions were inspired by the Relay-based router at Meta, where some features of Server Components were originally developed, as well as client-side routers like React Router and Ember.js. The
\\nlayout.js
file convention was inspired by the work done in SvelteKit. We\'d also like to thank Cassidy for opening an earlier RFC on layouts.
This RFC introduces new routing conventions and syntax. The terminology is based on React and standard web platform terms. Throughout the RFC, you\'ll see these terms linked back to their definitions below.
\\nToday, Next.js uses the file system to map individual folders and files in the Pages directory to routes accessible through URLs. Each page file exports a React Component and has an associated route based on its file name. For example:
\\n[param].js
, [...param].js
and [[...param]].js
conventions.getStaticProps
, getServerSideProps
) which can be used at the page (route) level. These methods are used to determine if a page should be Statically Generated (getStaticProps
) or Server-Side Rendered (getServerSideProps
). In addition, you can use Incremental Static Regeneration (ISR) to create or update static pages after a site is built.getServerSideProps
).app
Directory\\n \\n \\n \\n \\nTo ensure these new improvements can be incrementally adopted and avoid breaking changes, we are proposing a new directory called app
.
The app
directory will work alongside the pages
directory. You can incrementally move parts of your application to the new app
directory to take advantage of the new features. For backwards compatibility, the behavior of the pages
directory will remain the same and continue to be supported.
You can use the folder hierarchy inside app
to define routes. A route is a single path of nested folders, following the hierarchy from the root folder down to a final leaf folder.
For example, you can add a new /dashboard/settings
route by nesting two new folders in the app
directory.
\\n\\nNote:
\\n\\n
\\n- With this system, you\'ll use folders to define routes, and files to define UI (with new file conventions such as
\\nlayout.js
,page.js
, and in the second part of the RFCloading.js
).- This allows you to colocate your own project files (UI components, test files, stories, etc) inside the
\\napp
directory. Currently this is only possible with the pageExtensions config.
Each folder in the subtree represents a route segment. Each route segment is mapped to a corresponding segment in a URL path.
\\nFor example, the /dashboard/settings
route is composed of 3 segments:
/
root segmentdashboard
segmentsettings
segment\\n\\nNote: The name route segment was chosen to match the existing terminology around URL paths.
\\n
New file convention: layout.js
So far, we have used folders to define the routes of our application. But empty folders do not do anything by themselves. Let\'s discuss how you can define the UI that will render for these routes using new file conventions.
\\nA layout is UI that is shared between route segments in a subtree. Layouts do not affect URL paths and do not re-render (React state is preserved) when a user navigates between sibling segments.
\\nA layout can be defined by default exporting a React component from a layout.js
file. The component should accept a children
prop which will be populated with the segments the layout is wrapping.
There are 2 types of layouts:
\\nYou can nest two or more layouts together to form nested layouts.
\\nYou can create a root layout that will apply to all routes of your application by adding a layout.js
file inside the app
folder.
\\n\\nNote:
\\n\\n
\\n- The root layout replaces the need for a custom App (
\\n_app.js
) and custom Document (_document.js
) since it applies to all routes.- You\'ll be able to use the root layout to customize the initial document shell (e.g.
\\n<html>
and<body>
tags).- You\'ll be able to fetch data inside the root layout (and other layouts).
\\n
You can also create a layout that only applies to a part of your application by adding a layout.js
file inside a specific folder.
For example, you can create a layout.js
file inside the dashboard
folder which will only apply to the route segments inside dashboard
.
Layouts are nested by default.
\\nFor example, if we were to combine the two layouts above. The root layout (app/layout.js
) would be applied to the dashboard
layout, which would also apply to all route segments inside dashboard/*
.
New file convention: page.js
A page is UI that is unique to a route segment. You can create a page by adding a page.js
file inside a folder.
For example, to create pages for the /dashboard/*
routes, you can add a page.js
file inside each folder. When a user visits /dashboard/settings
, Next.js will render the page.js
file for the settings
folder wrapped in any layouts that exist further up the subtree.
You can create a page.js
file directly inside the dashboard folder to match the /dashboard
route. The dashboard layout will also apply to this page:
This route is composed of 2 segments:
\\n/
root segmentdashboard
segment\\n\\nNote:
\\n\\n
\\n- For a route to be valid, it needs to have a page in its leaf segment. If it doesn\'t, the route will throw an error.
\\n
js|jsx|ts|tsx
can be used for Pages and Layouts.page.js
.layout.js
.children
prop.When a layout component is rendered, the children
prop will be populated with a child layout (if it exists further down the subtree) or a page.
It may be easier to visualize it as a layout tree where the parent layout will pick the nearest child layout until it reaches a page.
\\nExample:
\\n// Root layout\\n// - Applies to all routes\\nexport default function RootLayout({ children }) {\\n return (\\n <html>\\n <body>\\n <Header />\\n {children}\\n <Footer />\\n </body>\\n </html>\\n );\\n}
// Regular layout\\n// - Applies to route segments in app/dashboard/*\\nexport default function DashboardLayout({ children }) {\\n return (\\n <>\\n <DashboardSidebar />\\n {children}\\n </>\\n );\\n}
// Page Component\\n// - The UI for the `app/dashboard/analytics` segment\\n// - Matches the `acme.com/dashboard/analytics` URL path\\nexport default function AnalyticsPage() {\\n return <main>...</main>;\\n}
The above combination of layouts and pages would render the following component hierarchy:
\\n<RootLayout>\\n <Header />\\n <DashboardLayout>\\n <DashboardSidebar />\\n <AnalyticsPage>\\n <main>...</main>\\n </AnalyticsPage>\\n </DashboardLayout>\\n <Footer />\\n</RootLayout>
\\n\\nNote: React introduced new component types: Server, Client (traditional React components), and Shared. To learn more about these new types, we recommend reading the React Server Components RFC.
\\n
With this RFC, you can start using React features and incrementally adopt React Server Components into your Next.js application.
\\nThe internals of the new routing system will also leverage recently released React features such as Streaming, Suspense, and Transitions. These are the building blocks for React Server Components.
\\nOne of the biggest changes between the pages
and app
directories is that, by default, files inside app
will be rendered on the server as React Server Components.
This will allow you to automatically adopt React Server Components when migrating from pages
to app
.
\\n\\nNote:\\nServer components can be used in the
\\napp
folder or your own folders, but cannot be used in thepages
directory for backwards compatibility.
The app
folder will support server, client, and shared components, and you\'ll be able to interleave these components in a tree.
There is an ongoing discussion on what exactly the convention will be for defining Client Components and Server Components. We will follow the resolution of this discussion.
\\n.server.js
to the filename. E.g. layout.server.js
.client.js
to the filename. E.g. page.client.js
..js
files are considered shared components. Since they could be rendered on the Server and the Client, they need to respect the constraints of each context.\\n\\nNote:
\\n\\n
\\n- Client and Server components have constraints that need to be respected. When deciding to use a client or server component, we recommend using server components (default) until you need to use a client component.
\\n
We\'ll be adding Client and Server component hooks that’ll allow you to access the headers object, cookies, pathnames, search params, etc. In the future, we\'ll have documentation with more information.
\\nYou\'ll have granular control of what components will be in the client-side JavaScript bundle using the Client and Server Components convention.
\\nBy default, routes in app
will use Static Generation, and will switch to dynamic rendering when a route segment uses server-side hooks that require request context.
In React, there\'s a restriction around importing Server Components inside Client Components because Server Components might have server-only code (e.g. database or filesystem utilities).
\\nFor example, importing the Server Component would not work:
\\nimport ServerComponent from \'./ServerComponent.js\';\\n \\nexport default function ClientComponent() {\\n return (\\n <>\\n <ServerComponent />\\n </>\\n );\\n}
However, a Server Component can be passed as a child of a Client Component. You can do this by wrapping them in another Server Component. For example:
\\nexport default function ClientComponent({ children }) {\\n return (\\n <>\\n <h1>Client Component</h1>\\n {children}\\n </>\\n );\\n}\\n \\n// ServerComponent.js\\nexport default function ServerComponent() {\\n return (\\n <>\\n <h1>Server Component</h1>\\n </>\\n );\\n}\\n \\n// page.js\\n// It\'s possible to import Client and Server components inside Server Components\\n// because this component is rendered on the server\\nimport ClientComponent from \\"./ClientComponent.js\\";\\nimport ServerComponent from \\"./ServerComponent.js\\";\\n \\nexport default function ServerComponentPage() {\\n return (\\n <>\\n <ClientComponent>\\n <ServerComponent />\\n </ClientComponent>\\n </>\\n );\\n}
With this pattern, React will know it needs to render ServerComponent
on the server before sending the result (which doesn\'t contain any server-only code) to the client. From the Client Component\'s perspective, its child will be already rendered.
In layouts, this pattern is applied with the children
prop so you don\'t have to create an additional wrapper component.
For example, the ClientLayout
component will accept the ServerPage
component as its child:
// The Dashboard Layout is a Client Component\\nexport default function ClientLayout({ children }) {\\n // Can use useState / useEffect here\\n return (\\n <>\\n <h1>Layout</h1>\\n {children}\\n </>\\n );\\n}\\n \\n// The Page is a Server Component that will be passed to Dashboard Layout\\n// app/dashboard/settings/page.js\\nexport default function ServerPage() {\\n return (\\n <>\\n <h1>Page</h1>\\n </>\\n );\\n}
\\n\\nNote: This style of composition is an important pattern for rendering Server Components inside Client Components. It sets the precedence of one pattern to learn, and is one of the reasons why we\'ve decided to use the
\\nchildren
prop.
It will be possible to fetch data inside multiple segments in a route. This is different from the pages
directory, where data fetching was limited to the page-level.
You can fetch data in a layout.js
file by using the Next.js data fetching methods getStaticProps
or getServerSideProps
.
For example, a blog layout could use getStaticProps
to fetch categories from a CMS, which can be used to populate a sidebar component:
export async function getStaticProps() {\\n const categories = await getCategoriesFromCMS();\\n \\n return {\\n props: { categories },\\n };\\n}\\n \\nexport default function BlogLayout({ categories, children }) {\\n return (\\n <>\\n <BlogSidebar categories={categories} />\\n {children}\\n </>\\n );\\n}
You can also fetch data in multiple segments of a route. For example, a layout
that fetches data can also wrap a page
that fetches its own data.
Using the blog example above, a single post page can use getStaticProps
and getStaticPaths
to fetch post data from a CMS:
export async function getStaticPaths() {\\n const posts = await getPostSlugsFromCMS();\\n \\n return {\\n paths: posts.map((post) => ({\\n params: { slug: post.slug },\\n })),\\n };\\n}\\n \\nexport async function getStaticProps({ params }) {\\n const post = await getPostFromCMS(params.slug);\\n \\n return {\\n props: { post },\\n };\\n}\\n \\nexport default function BlogPostPage({ post }) {\\n return <Post post={post} />;\\n}
Since both app/blog/layout.js
and app/blog/[slug]/page.js
use getStaticProps
, Next.js will statically generate the whole /blog/[slug]
route as React Server Components at build time - resulting in less client-side JavaScript and faster hydration.
Statically generated routes improve this further, as the client navigation reuses the cache (Server Components data) and doesn\'t recompute work, leading to less CPU time because you\'re rendering a snapshot of the Server Components.
\\nNext.js Data Fetching Methods (getServerSideProps
and getStaticProps
) can only be used in Server Components in the app
folder. Different data fetching methods in segments across a single route affect each other.
Using getServerSideProps
in one segment will affect getStaticProps
in other segments. Since a request already has to go to a server for the getServerSideProps
segment, the server will also render any getStaticProps
segments. It will reuse the props fetched at build time so the data will still be static, the rendering happens on-demand on every request with the props generated during next build
.
Using getStaticProps
with revalidate (ISR) in one segment will affect getStaticProps
with revalidate
in other segments. If there are two revalidate periods in one route, the shorter revalidation will take precedence.
\\n\\nNote: In the future, this may be optimized to allow for full data fetching granularity in a route.
\\n
The combination of Server-Side Routing, React Server Components, Suspense and Streaming have a few implications for data fetching and rendering in Next.js:
\\nNext.js will eagerly initiate data fetches in parallel to minimize waterfalls. For example, if data fetching was sequential, each nested segment in the route couldn\'t start fetching data until the previous segment was completed. With parallel fetching, however, each segment can eagerly start data fetching at the same time.
\\nSince rendering may depend on Context, rendering for each segment will start once its data has been fetched and its parent has finished rendering.
\\nIn the future, with Suspense, rendering could also start immediately - even if the data is not completely loaded. If the data is read before it\'s available, Suspense will be triggered. React will start rendering Server Components optimistically, before the requests have completed, and will slot in the result as the requests resolve.
\\nWhen navigating between sibling route segments, Next.js will only fetch and render from that segment down. It will not need to re-fetch or re-render anything above. This means in a page that shares a layout, the layout will be preserved when a user navigates between sibling pages, and Next.js will only fetch and render from that segment down.
\\nThis is especially useful for React Server Components, as otherwise each navigation would cause the full page to re-render on the server instead of rendering only the changed part of the page on the server. This reduces the amount of data transfered and execution time, leading to improved performance.
\\nFor example, if the user navigates between the /analytics
and the /settings
pages, React will re-render the page segments but preserve the layouts:
\\n\\nNote: It will be possible to force a re-fetch of data higher up the tree. We are still discussing the details of how this will look and will update the RFC.
\\n
The hierarchy of the app
folder maps directly to URL paths. But it’s possible to break out of this pattern by creating a route group. Route groups can be used to:
A route group can be created by wrapping a folder’s name in parenthesis: (folderName)
\\n\\nNote: The naming of route groups are only for organizational purposes since they do not affect the URL path.
\\n
Example: Opting a route out of a layout
\\nTo opt a route out of a layout, create a new route group (e.g. (shop)
) and move the routes that share the same layout into the group (e.g. account
and cart
). The routes outside of the group will not share the layout (e.g. checkout
).
Before:
\\nAfter:
\\nExample: Organizing routes without affecting the URL path
\\nSimilarly, to organize routes, create a group to keep related routes together. The folders in parenthesis will be omitted from the URL (e.g. (marketing)
or (shop)
).
Example: Creating multiple root layouts
\\nTo create multiple root layouts, create two or more route groups at the top level of the app
directory. This is useful for partitioning an application into sections that have a completely different UI or experience. The <html>
, <body>
and <head>
tags of each root layout can be customized separately.
Currently, Next.js uses client-side routing. After the initial load and on subsequent navigation, a request is made to the server for the resources of the new page. This includes the JavaScript for every component (including components only shown under certain conditions) and their props (JSON data from getServerSideProps
or getStaticProps
). Once both the JavaScript and data are loaded from the server, React renders the components client-side.
In this new model, Next.js will use server-centric routing while maintaining client-side transitions. This aligns with Server Components which are evaluated on the server.
\\nOn navigation, data is fetched and React renders the components server-side. The output from the server are special instructions (not HTML or JSON) for React on the client to update the DOM. These instructions hold the result of the rendered Server Components meaning that no JavaScript for that component has to be loaded in the browser to render the result.
\\nThis is in contrast to the current default of Client components, which the component JavaScript to the browser to be rendered client-side.
\\nSome benefits of server-centric routing with React Server Components include:
\\nAs users navigate around an app, the router will store the result of the React Server Component payload in an in-memory client-side cache. The cache is split by route segments which allows invalidation at any level and ensures consistency across concurrent renders. This means that for certain cases, the cache of a previously fetched segment can be re-used.
\\n\\n\\nNote
\\n\\n
\\n- Static Generation and Server-side caching can be used to optimize data fetching.
\\n- The information above describes the behavior of subsequent navigations. The initial load is a different process involving Server Side Rendering to generate HTML.
\\n- While client-side routing has worked well for Next.js, it scales poorly when the number of potential routes is large because the client has to download a route map.
\\n- Overall, by using React Server Components, client-side navigation is faster because we load and render less components in the browser.
\\n
With server-side routing, navigation happens after data fetching and rendering so it’s important to show loading UI while the data is being fetched otherwise the application will seem unresponsive.
\\nThe new router will use Suspense for instant loading states and default skeletons. This means loading UI can be shown immediately while the content for the new segment loads. The new content is then swapped in once rendering on the server is complete.
\\nWhile rendering is happening:
\\nSuspense boundaries will be automatically handled behind-the-scenes with a new file convention called loading.js
.
Example:
\\nYou will be able to create a default loading skeleton by adding a loading.js
file inside a folder.
The loading.js
should export a React component:
export default function Loading() {\\n return <YourSkeleton />\\n}\\n \\n// layout.js\\nexport default function Layout({children}) {\\n return (\\n <>\\n <Sidebar />\\n {children}\\n </>\\n )\\n}\\n \\n// Output\\n<>\\n <Sidebar />\\n <Suspense fallback={<Loading />}>{children}</Suspense>\\n</>
This will cause all segments in the folder to be wrapped in a suspense boundary. The default skeleton will be used when the layout is first loaded and when navigating between sibling pages.
\\nError boundaries are React components that catch JavaScript errors anywhere in their child component tree.
\\nYou\'ll be able to create an Error Boundary that will catch errors within a subtree by adding a error.js
file and default exporting a React Component.
The Component will be shown as a fallback if an error is thrown within that subtree. This component can be used to log errors, display useful information about the error, and functionality to attempt to recover from the error.
\\nDue to the nested nature of segments and layouts, creating Error boundaries allows you to isolate errors to those parts of the UI. During an error, layouts above the boundary will remain interactive and their state will be preserved.
\\nexport default function Error({ error, reset }) {\\n return (\\n <>\\n An error occurred: {error.message}\\n <button onClick={() => reset()}>Try again</button>\\n </>\\n );\\n}\\n \\n// layout.js\\nexport default function Layout({children}) {\\n return (\\n <>\\n <Sidebar />\\n {children}\\n </>\\n )\\n}\\n \\n// Output\\n<>\\n <Sidebar />\\n <ErrorBoundary fallback={<Error />}>{children}</ErrorBoundary>\\n</>
\\n\\nNote:
\\n\\n
\\n- Errors inside a
\\nlayout.js
file in the same segment as anerror.js
will not be caught as the automatic error boundary wraps the children of a layout and not the layout itself.
Templates are similar to Layouts in that they wrap each child Layout or Page.
\\nUnlike Layouts that persist across routes and maintain state, templates create a new instance for each of their children. This means that when a user navigates between route segments that share a template, a new instance of the component is mounted.
\\n\\n\\nNote: We recommend using Layouts unless you have a specific reason to use a Template.
\\n
A template can be defined by exporting a default React component from a template.js
file. The component should accept a children
prop which will be populated with nested segments.
export default function Template({ children }) {\\n return <Container>{children}</Container>;\\n}
The rendered output of a route segment with a Layout and a Template will be as such:
\\n<Layout>\\n {/* Note that the template is given a unique key. */}\\n <Template key={routeParam}>{children}</Template>\\n</Layout>
There may be cases where you need to mount and unmount shared UI, and templates would be a more suitable option. For example:
\\nuseEffect
(e.g logging page views) and useState
(e.g a per-page feedback form)For example, consider the design of a nested layout with a bordered container that should be wrapped around every sub-page.
\\nYou could put the container inside the parent layout (shop/layout.js
):
export default function Layout({ children }) {\\n return <div className=\\"container\\">{children}</div>;\\n}\\n \\n// shop/page.js\\nexport default function Page() {\\n return <div>...</div>;\\n}\\n \\n// shop/categories/layout.js\\nexport default function CategoryLayout({ children }) {\\n return <div>{children}</div>;\\n}
But any enter/exit animations wouldn’t play when switching pages because the shared parent layout doesn’t re-render.
\\nYou could put the container in every nested layout or page:
\\nexport default function Layout({ children }) {\\n return <div>{children}</div>;\\n}\\n \\n// shop/page.js\\nexport default function Page() {\\n return <div className=\\"container\\">...</div>;\\n}\\n \\n// shop/categories/layout.js\\nexport default function CategoryLayout({ children }) {\\n return <div className=\\"container\\">{children}</div>;\\n}
But then you’d have to manually put it in every nested layout or page which can be tedious and error-prone in more complex apps.
\\nWith this convention, you can share templates across routes that create a new instance on navigation. This means DOM elements will be recreated, state will not be preserved, and effects will be re-synchronized.
\\nWe plan to introduce conventions to cover edge cases and allow you to implement more advanced routing patterns. Below are some examples we have been actively thinking about:
\\nSometimes, it may be useful to intercept route segments from within other routes. On navigation, the URL will be updated as normal, but the intercepted segment will be shown within the current route’s layout.
\\nBefore: Clicking the image leads to a new route with its own layout.
\\nAfter: By intercepting the route, clicking the image now loads the segment within the current route’s layout. E.g. as a modal.
\\nTo intercept the /photo/[id]
route from within /[username]
segment, create a duplicate /photo/[id]
folder inside the /[username]
folder, and prefix it with the (..)
convention.
(..)
- will match the route segment one level higher (sibling of the parent directory). Similar to ../
in relative paths.(..)(..)
- will match the route segment two levels higher. Similar to ../../
in relative paths.(...)
- will match the route segment in the root directory.\\n\\nNote: Refreshing or sharing the page would load the route with its default layout.
\\n
Sometimes it may be useful to show two or more leaf segments (page.js
) in the same view that can be navigated independently.
Take for instance two or more tab groups within the same dashboard. Navigating one tab group should not affect the other. The combinations of tabs should also be correctly restored when navigating backwards and forwards.
\\nBy default, layouts accept a prop called children
which will contain a nested layout or a page. You can rename the prop by creating a named \\"slot\\" (a folder that includes the @
prefix) and nesting segments inside it.
After this change, the layout will receive a prop called customProp
instead of children
.
export default function Layout({ customProp }) {\\n return <>{customProp}</>;\\n}
You can create parallel routes by adding more than one named slot at the same level. In the example below, both @views
and @audience
are passed as props to the analytics layout.
You can use the named slots to display leaf segments simultaneously.
\\nexport default function Layout({ views, audience }) {\\n return (\\n <>\\n <div>\\n <ViewsNav />\\n {views}\\n </div>\\n <div>\\n <AudienceNav />\\n {audience}\\n </div>\\n </>\\n );\\n}
When the user first navigates to /analytics
, the page.js
segment in each folder (@views
and @audience
) are shown.
On navigation to /analytics/subscribers
, only @audience
is updated. Similarly, only @views
are updated when navigating to /analytics/impressions
.
Navigating backwards and forwards will reinstate the correct combination of parallel routes.
\\nYou can combine intercepting and parallel routes to achieve specific routing behaviors in your application.
\\nExample
\\nFor example, when creating a modal, you often need to be aware of some common challenges, such as:
\\nYou may want the modal to update the URL when it opens, and backwards/fowards navigation to open and close the modal. Additionally, when sharing the URL, you may want the page to load with the modal open and context behind it or you may want the page to load the content without the modal.
\\nA good example of this are photos on social media sites. Usually, photos are accessible within a modal from the user\'s feed or profile. But when sharing the photo, they shown directly on their own page.
\\nBy using conventions, we can make the modal behavior map to routing behavior by default.
\\nConsider this folder structure:
\\nWith this pattern:
\\n/photo/[id]
is accessible through an URL within its own context. It\'s also accessible within a modal from within the /[username]
route./photo/id
route instead of showing the modal.In /@modal/(..)photo/[id]/page.js
, you can return the content of the page wrapped in a modal component.
export default function PhotoPage() {\\n const router = useRouter();\\n \\n return (\\n <Modal\\n // the modal should always be shown on page load\\n isOpen={true}\\n // closing the modal should take user back to the previous page\\n onClose={() => router.back()}\\n >\\n {/* Page Content */}\\n </Modal>\\n );\\n}
\\n\\nNote: This solution isn\'t the only way to create a modal in Next.js, but aims to show how you can combine conventions to achieve more complex routing behavior.
\\n
Sometimes, you may need dynamic information like data or context to determine what route to show. You can use parallel routes to conditionally load one route or another.
\\nExample
\\nexport async function getServerSideProps({ params }) {\\n const { accountType } = await fetchAccount(params.slug);\\n return { props: { isUser: accountType === \'user\' } };\\n}\\n \\nexport default function UserOrTeamLayout({ isUser, user, team }) {\\n return <>{isUser ? user : team}</>;\\n}
In the example above, you can return either the user
or team
route depending on the slug. This allows you to conditionally load the data and match the sub-routes against one option or the other.
We\'re excited about the future of layouts, routing, and React 18 in Next.js. Implementation work has begun and we\'ll announce the features once they are available.
\\nLeave comments and join the conversation on GitHub Discussions.
","description":"This RFC (Request for Comment) outlines the biggest update to Next.js since it was introduced in 2016: Nested Layouts: Build complex applications with nested routes.\\nDesigned for Server Components: Optimized for subtree navigation.\\nImproved Data Fetching: Fetch in layouts while…","guid":"https://nextjs.org/blog/layouts-rfc","author":null,"authorUrl":null,"authorAvatar":null,"publishedAt":"2024-10-24T18:55:48.102Z","media":[{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Fterminology.png&w=3840&q=75","type":"photo","width":1798,"height":615},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Fterminology.png&w=3840&q=75","type":"photo","width":1798,"height":615},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Furl-anatomy.png&w=3840&q=75","type":"photo","width":1798,"height":407},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Furl-anatomy.png&w=3840&q=75","type":"photo","width":1798,"height":407},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Frouting-today.png&w=3840&q=75","type":"photo","width":1798,"height":605},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Frouting-today.png&w=3840&q=75","type":"photo","width":1798,"height":605},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Fapp-folder.png&w=3840&q=75","type":"photo","width":3596,"height":1534},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Fapp-folder.png&w=3840&q=75","type":"photo","width":3596,"height":1534},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Froutes.png&w=3840&q=75","type":"photo","width":3596,"height":1280},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Froutes.png&w=3840&q=75","type":"photo","width":3596,"height":1280},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Froute-segments.png&w=3840&q=75","type":"photo","width":3596,"height":1512},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Froute-segments.png&w=3840&q=75","type":"photo","width":3596,"height":1512},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Froot-layout.png&w=3840&q=75","type":"photo","width":3596,"height":1210},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Froot-layout.png&w=3840&q=75","type":"photo","width":3596,"height":1210},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Fregular-layouts.png&w=3840&q=75","type":"photo","width":3596,"height":1696},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Fregular-layouts.png&w=3840&q=75","type":"photo","width":3596,"height":1696},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Fnested-layouts.png&w=3840&q=75","type":"photo","width":3596,"height":1696},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Fnested-layouts.png&w=3840&q=75","type":"photo","width":3596,"height":1696},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Fnested-layouts-example.png&w=3840&q=75","type":"photo","width":3596,"height":1668},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Fnested-layouts-example.png&w=3840&q=75","type":"photo","width":3596,"height":1668},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Fpage.png&w=3840&q=75","type":"photo","width":3596,"height":1696},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Fpage.png&w=3840&q=75","type":"photo","width":3596,"height":1696},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Fpage-example.png&w=3840&q=75","type":"photo","width":3596,"height":1668},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Fpage-example.png&w=3840&q=75","type":"photo","width":3596,"height":1668},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Fpage-nested.png&w=3840&q=75","type":"photo","width":3596,"height":1858},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Fpage-nested.png&w=3840&q=75","type":"photo","width":3596,"height":1858},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Fbasic-example.png&w=3840&q=75","type":"photo","width":3596,"height":1372},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Fbasic-example.png&w=3840&q=75","type":"photo","width":3596,"height":1372},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Fserver-components.png&w=3840&q=75","type":"photo","width":3596,"height":1230},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Fserver-components.png&w=3840&q=75","type":"photo","width":3596,"height":1230},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Fparallel.png&w=3840&q=75","type":"photo","width":3596,"height":1386},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Fparallel.png&w=3840&q=75","type":"photo","width":3596,"height":1386},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Fpartial-example.png&w=3840&q=75","type":"photo","width":3596,"height":1880},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Fpartial-example.png&w=3840&q=75","type":"photo","width":3596,"height":1880},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Froute-group-opt-out-before.png&w=3840&q=75","type":"photo","width":3596,"height":1880},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Froute-group-opt-out-before.png&w=3840&q=75","type":"photo","width":3596,"height":1880},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Froute-group-opt-out-after.png&w=3840&q=75","type":"photo","width":3596,"height":1880},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Froute-group-opt-out-after.png&w=3840&q=75","type":"photo","width":3596,"height":1880},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Froute-group-organisation.png&w=3840&q=75","type":"photo","width":3596,"height":1880},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Froute-group-organisation.png&w=3840&q=75","type":"photo","width":3596,"height":1880},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Froute-group-multiple-root.png&w=3840&q=75","type":"photo","width":3596,"height":1880},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Froute-group-multiple-root.png&w=3840&q=75","type":"photo","width":3596,"height":1880},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Fserver-side-routing.png&w=3840&q=75","type":"photo","width":3596,"height":1880},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Fserver-side-routing.png&w=3840&q=75","type":"photo","width":3596,"height":1880},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Floading.png&w=3840&q=75","type":"photo","width":3596,"height":1880},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Floading.png&w=3840&q=75","type":"photo","width":3596,"height":1880},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Ferror.png&w=3840&q=75","type":"photo","width":3596,"height":1230},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Ferror.png&w=3840&q=75","type":"photo","width":3596,"height":1230},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Ftemplate.png&w=3840&q=75","type":"photo","width":3596,"height":1230},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Ftemplate.png&w=3840&q=75","type":"photo","width":3596,"height":1230},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Fintercepted-routes-before.png&w=3840&q=75","type":"photo","width":3596,"height":1880},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Fintercepted-routes-before.png&w=3840&q=75","type":"photo","width":3596,"height":1880},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Fintercepted-routes-after.png&w=3840&q=75","type":"photo","width":3596,"height":1880},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Fintercepted-routes-after.png&w=3840&q=75","type":"photo","width":3596,"height":1880},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Fintercepted-route.png&w=3840&q=75","type":"photo","width":3596,"height":1880},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Fintercepted-route.png&w=3840&q=75","type":"photo","width":3596,"height":1880},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Fparallel-routes.png&w=3840&q=75","type":"photo","width":3596,"height":1880},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Fparallel-routes.png&w=3840&q=75","type":"photo","width":3596,"height":1880},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Fparallel-routes-children.png&w=3840&q=75","type":"photo","width":3596,"height":1880},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Fparallel-routes-children.png&w=3840&q=75","type":"photo","width":3596,"height":1880},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Fparallel-routes-complete.png&w=3840&q=75","type":"photo","width":3596,"height":1880},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Fparallel-routes-complete.png&w=3840&q=75","type":"photo","width":3596,"height":1880},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Fintercepted-route-modal.png&w=3840&q=75","type":"photo","width":3596,"height":1880},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Flayouts-rfc%2Fintercepted-route-modal.png&w=3840&q=75","type":"photo","width":3596,"height":1880}],"categories":null,"attachments":null,"extra":null,"language":null},{"title":"Our Journey with Caching","url":"https://nextjs.org/blog/our-journey-with-caching","content":"Frontend performance can be hard to get right. Even in highly optimized apps, the most common culprit by far is client-server waterfalls. When introducing Next.js App Router, we knew we wanted to solve this issue. To do that, we needed to move client-server REST fetches to the server using React Server Components in a single roundtrip. This meant the server had to sometimes be dynamic, sacrificing the great initial loading performance of Jamstack. We built partial prerendering to solve this tradeoff and have the best of both worlds.
\\nHowever, along the way, the developer experience suffered due to the caching defaults and controls we provided. The default for fetch()
changed to favor performance by caching by default, but quick prototyping and highly dynamic apps suffered. We didn\'t provide enough control over local database access that wasn\'t using fetch()
. We had unstable_cache()
, but it wasn\'t ergonomic. This led to the need for segment-level configs, such as export const dynamic, runtime, fetchCache, dynamicParams, revalidate = ...
, as an escape hatch.
We\'ll continue supporting that for backward compatibility, of course. But for a moment, I\'d like you to forget about all that. We think we have an idea for something simpler.
\\nWe\'ve been cooking on a new experimental mode that builds on just two concepts: <Suspense>
and use cache
.
The first thing you\'ll notice is that when you add data to your components, you will now get an error.
\\nasync function Component() {\\n return fetch(...) // error\\n}\\n \\nexport default async function Page() {\\n return <Component />\\n}
To use data, cookies, headers, current time or random values, you now have a choice: do you want the data to be cached (server or client-side) or executed on every request? I\'m using fetch()
as an example, but this applies to any async Node API, such as databases or timers.
If you\'re still iterating or building a highly dynamic dashboard, you can wrap the component in a <Suspense>
boundary. <Suspense>
opts into dynamic data fetching and streaming.
async function Component() {\\n return fetch(...) // no error\\n}\\n \\nexport default async function Page() {\\n return <Suspense fallback=\\"...\\"><Component /></Suspense>\\n}
You can also do this in your root layout or use loading.tsx
.
This ensures that the shell of your app remains instant. You can continue adding more data inside your Page, knowing it will all be dynamic by default. Nothing is cached by default. No more hidden caches.
\\nIf you\'re building something static and don\'t want to use dynamic functionality, you can use the new use cache
directive.
\\"use cache\\"\\n \\nexport default async function Page() {\\n return fetch(...) // no error\\n}
By marking the Page with use cache
, you\'re indicating that the entire segment should be cached. This means any data you fetch can now be cached, allowing the page to be statically rendered. No <Suspense>
boundary is used for static content. You can add more data to the page, and it will all be cached.
You can also mix and match. For example, you can put use cache
in your root layout to ensure it is cached. Each layout or page can be cached independently.
\\"use cache\\"\\n \\nexport default async function Layout({ children }) {\\n const response = await fetch(...)\\n const data = await response.json()\\n return <html>\\n <body>\\n <div>{data.notice}</div>\\n {children}\\n </body>\\n </html>\\n}
While using dynamic data within a specific Page:
\\nimport { Suspense } from \'react\'\\nasync function Component() {\\n return fetch(...) // no error\\n}\\n \\nexport default async function Page() {\\n return <Suspense fallback=\\"...\\"><Component /></Suspense>\\n}
When using a hybrid approach like this, it might be more convenient to add caching closer to the API calls.
\\nYou can add use cache
to any async function, just like use server
. Think of it as a Server Action but instead of calling a Server you\'re calling a Cache. It supports the same rich types of arguments and return values beyond just JSON. The cache key automatically includes any arguments and closures, so you don\'t need to specify a cache key manually.
async function getNotice() {\\n \\"use cache\\"\\n const response = await fetch(...)\\n const data = await response.json()\\n return data.notice;\\n}\\n \\nexport default async function Layout({ children }) {\\n return <html>\\n <body>\\n <h1>{await getNotice()}</h1>\\n {children}\\n </body>\\n </html>\\n}
Since no other data was used in this layout, it can remain static. A benefit of this approach is that if you accidentally add new dynamic data to the layout, it will trigger an error during the build, forcing you to make a new choice. If you add use cache
to the entire layout, it will be cached with no error. Which approach you choose depends on your use case.
If you want to explicitly clear a cache entry by tag, you can use the new cacheTag()
API inside the use cache
function.
import { cacheTag } from \'next/cache\';\\n \\nasync function getNotice() {\\n \'use cache\';\\n cacheTag(\'my-tag\');\\n}
Then, just call revalidateTag(\'my-tag\')
from a Server Action as before.
Since this API can be called after data loading, you can now use data to tag your cache entries.
\\nimport { unstable_cacheTag as cacheTag } from \'next/cache\';\\n \\nasync function getBlogPosts(page) {\\n \'use cache\';\\n const posts = await fetchPosts(page);\\n for (let post of posts) {\\n cacheTag(\'blog-post-\' + post.id);\\n }\\n return posts;\\n}
If you want to control how long a particular entry or page should live in the cache, you can use the cacheLife()
API:
\\"use cache\\"\\nimport { unstable_cacheLife as cacheLife } from \'next/cache\'\\n \\nexport default async function Page() {\\n cacheLife(\\"minutes\\")\\n return ...\\n}
By default, it accepts the following values:
\\n\\"seconds\\"
\\"minutes\\"
\\"hours\\"
\\"days\\"
\\"weeks\\"
\\"max\\"
Choose a rough range that bests fits your use case. No need to specify an exact number and calculate how many seconds (or was it milliseconds?) are in a week. However, you can also specify specific values or configure your own named cache profiles.
\\nIn addition to revalidate
, this API can control the stale
time of the client cache as well as expire
, which dictates when a Page should expire if it hasn\'t had much traffic for a while.
This is still very much an experimental project. It\'s not production-ready yet and still has missing features and bugs. In particular, we know we need to improve the error stacks for this new type of error. However, if you\'re feeling adventurous, we\'d love your early feedback.
\\nWe will publish a more detailed upgrade path. Aside from the early errors, the main breaking change here is undoing the default caching of fetch()
. That said, we recommend experimenting only on greenfield projects at this early experimental stage. If it pans out well we hope to ship an opt-in version in a minor and make it the default in a future major.
To play with it, you must be on the canary
version of Next.js:
npx create-next-app@latest
You must also enable the experimental dynamicIO flag in next.config.ts
:
import type { NextConfig } from \'next\';\\n \\nconst nextConfig: NextConfig = {\\n experimental: {\\n dynamicIO: true,\\n }\\n};\\n \\nexport default nextConfig;
Read more about use cache
, cacheLife
, and cacheTag
in our documentation.
Following the announcement of the first Next.js 15 Release Candidate back in May, we’ve been preparing a second Release Candidate based on your feedback. Here’s what we’ve been working on:
\\n@next/codemod upgrade
: Easily upgrade to the latest Next.js and React versions.next/form
: Enhance HTML forms with client-side navigation.next.config.ts
: TypeScript support for the Next.js configuration file.instrumentation.js
(Stable): New API for server lifecycle observability.Cache-Control
headers.Try the Next.js 15 Release Candidate (RC2) today:
\\n# Use the new automated upgrade CLI\\nnpx @next/codemod@canary upgrade rc\\n \\n# ...or upgrade manually\\nnpm install next@rc react@rc react-dom@rc
\\n\\nNote: This Release Candidate includes all changes from the previous RC.
\\n
We include codemods (automated code transformations) with every major Next.js release to help automate upgrading breaking changes.
\\nTo make upgrades even smoother, we\'ve released an enhanced codemod CLI:
\\nnpx @next/codemod@canary upgrade rc
This tool helps you upgrade your codebase to the latest stable or prerelease versions. The CLI will update your dependencies, show available codemods, and guide you through applying them. The specified dist tag on the command line (@rc
, @canary
, etc.) determines the version to upgrade to.
Learn more about Next.js codemods.
\\nTurbopack for local development will become stable in the general release of Next.js 15, while remaining opt-in. You can try it today by running:
\\nnext dev --turbo
Thanks to the thousands of developers who participated in testing, reporting issues, and verifying fixes throughout the Turbopack beta and release candidate phases, we\'ve resolved 54 GitHub issues since the first Next.js 15 Release Candidate. Alongside this community effort, our internal testing on vercel.com, v0.dev, and nextjs.org helped identify numerous additional improvements.
\\nIn the last three months, we\'ve focused on optimizing cold compilation performance. Compared to the previous release, we\'ve seen:
\\nWe will continue to optimize these areas in future releases.
\\nLooking ahead, the Turbopack team is making significant progress on persistent caching, memory usage reduction, and Turbopack for next build
—with 96% of tests passing.
\\n\\nNote: See all of the supported and unsupported features of Turbopack.
\\n
In traditional Server-Side Rendering, the server waits for a request before rendering any content. However, not all components depend on request-specific data, so it\'s unnecessary to wait for the request to render them. Ideally, the server would prepare as much as possible before a request arrives. To enable this, and set the stage for future optimizations, we need to know when to wait for the request.
\\nTherefore, we are transitioning APIs that rely on request-specific data—such as headers
, cookies
, params
, and searchParams
—to be asynchronous.
import { cookies } from \'next/headers\';\\n \\nexport async function AdminPanel() {\\n const cookieStore = await cookies();\\n const token = cookieStore.get(\'token\');\\n \\n // ...\\n}
This is a breaking change and affects the following APIs:
\\ncookies
headers
draftMode
params
in layout.js
, page.js
, route.js
, default.js
, generateMetadata
, and generateViewport
searchParams
in page.js
For an easier migration, these APIs can temporarily be accessed synchronously, but will show warnings in development and production until the next major version. A codemod is available to automate the migration:
\\nnpx @next/codemod@canary next-async-request-api .
For cases where the codemod can\'t fully migrate your code, please read the upgrade guide. We have also provided an example of how to migrate a Next.js application to the new APIs.
\\nServer Actions are server-side functions that can be called from the client. They are defined by adding the \'use server\'
directive at the top of a file and exporting an async function.
Even if a Server Action or utility function is not imported elsewhere in your code, it’s still a publicly accessible HTTP endpoint. While this behavior is technically correct, it can lead to unintentional exposure of such functions.
\\nTo improve security, we’ve introduced the following enhancements:
\\n// app/actions.js\\n\'use server\';\\n \\n// This action **is** used in our application, so Next.js\\n// will create a secure ID to allow the client to reference\\n// and call the Server Action.\\nexport async function updateUserAction(formData) {}\\n \\n// This action **is not** used in our application, so Next.js\\n// will automatically remove this code during `next build`\\n// and will not create a public endpoint.\\nexport async function deleteUserAction(formData) {}
You should still treat Server Actions any public HTTP endpoints. Learn more about securing Server Actions.
\\nNext.js now displays a Static Route Indicator during development to help you identify which routes are static or dynamic. This visual cue makes it easier to optimize performance by understanding how your pages are rendered.
\\nYou can also use the next build output to view the rendering strategy for all routes.
\\nThis update is part of our ongoing efforts to enhance observability in Next.js, making it easier for developers to monitor, debug, and optimize their applications. We\'re also working on dedicated developer tools, with more details to come soon.
\\nLearn more about the Static Route Indicator, which can be disabled.
\\n<Form>
ComponentThe new <Form>
component extends the HTML <form>
element with prefetching, client-side navigation, and progressive enhancement.
It is useful for forms that navigate to a new page, such as a search form that leads to a results page.
\\nimport Form from \'next/form\';\\n \\nexport default function Page() {\\n return (\\n <Form action=\\"/search\\">\\n <input name=\\"query\\" />\\n <button type=\\"submit\\">Submit</button>\\n </Form>\\n );\\n}
The <Form>
component comes with:
Previously, achieving these features required a lot of manual boilerplate. For example:
\\n// Note: This is abbreviated for demonstration purposes.\\n// Not recommended for use in production code.\\n \\n\'use client\'\\n \\nimport { useEffect } from \'react\'\\nimport { useRouter } from \'next/navigation\'\\n \\nexport default function Form(props) {\\n const action = props.action\\n const router = useRouter()\\n \\n useEffect(() => {\\n // if form target is a URL, prefetch it\\n if (typeof action === \'string\') {\\n router.prefetch(action)\\n }\\n }, [action, router])\\n \\n function onSubmit(event) {\\n event.preventDefault()\\n \\n // grab all of the form fields and trigger a `router.push` with the data URL encoded\\n const formData = new FormData(event.currentTarget)\\n const data = new URLSearchParams()\\n \\n for (const [name, value] of formData) {\\n data.append(name, value as string)\\n }\\n \\n router.push(`${action}?${data.toString()}`)\\n }\\n \\n if (typeof action === \'string\') {\\n return <form onSubmit={onSubmit} {...props} />\\n }\\n \\n return <form {...props} />\\n}
Learn more about the <Form>
Component.
next.config.ts
Next.js now supports the TypeScript next.config.ts
file type and provides a NextConfig
type for autocomplete and type-safe options:
import type { NextConfig } from \'next\';\\n \\nconst nextConfig: NextConfig = {\\n /* config options here */\\n};\\n \\nexport default nextConfig;
Learn more about TypeScript support in Next.js.
\\ninstrumentation.js
(Stable)The instrumentation
file, with the register()
API, allows users to tap into the Next.js server lifecycle to monitor performance, track the source of errors, and deeply integrate with observability libraries like OpenTelemetry.
This feature is now stable and the experimental.instrumentationHook
config option can be removed.
In addition, we’ve collaborated with Sentry on designing a new onRequestError
hook that can be used to:
export async function onRequestError(err, request, context) {\\n await fetch(\'https://...\', {\\n method: \'POST\',\\n body: JSON.stringify({ message: err.message, request, context }),\\n headers: { \'Content-Type\': \'application/json\' },\\n });\\n}\\n \\nexport async function register() {\\n // init your favorite observability provider SDK\\n}
Learn more about the onRequestError
function.
During development, Server components are re-executed when saved. This means, any fetch
requests to your API endpoints or third-party services are also called.
To improve local development performance and reduce potential costs for billed API calls, we now ensure Hot Module Replacement (HMR) can re-use fetch
responses from previous renders.
Learn more about the Server Components HMR Cache.
\\nWe\'ve optimized static generation to improve build times, especially for pages with slow network requests.
\\nPreviously, our static optimization process rendered pages twice—once to generate data for client-side navigation and a second time to render the HTML for the initial page visit. Now, we reuse the first render, cutting out the second pass, reducing workload and build times.
\\nAdditionally, static generation workers now share the fetch
cache across pages. If a fetch
call doesn’t opt out of caching, its results are reused by other pages handled by the same worker. This reduces the number of requests for the same data.
We’ve added experimental support for more control over static generation process for advanced use cases that would benefit from greater control.
\\nWe recommend sticking to the current defaults unless you have specific requirements as these options can lead to increased resource usage and potential out-of-memory errors due to increased concurrency.
\\nconst nextConfig = {\\n experimental: {\\n // how many times Next.js will retry failed page generation attempts\\n // before failing the build\\n staticGenerationRetryCount: 1\\n // how many pages will be processed per worker\\n staticGenerationMaxConcurrency: 8\\n // the minimum number of pages before spinning up a new export worker\\n staticGenerationMinPagesPerWorker: 25\\n },\\n}\\n \\nexport default nextConfig;
Learn more about the Static Generation options.
\\nWhen self-hosting applications, you may need more control over Cache-Control
directives.
One common case is controlling the stale-while-revalidate
period sent for ISR pages. We\'ve implemented two improvements:
expireTime
value in next.config
. This was previously the experimental.swrDelta
option.stale-while-revalidate
semantics as intended.We also no longer override custom Cache-Control
values with our default values, allowing full control and ensuring compatibility with any CDN setup.
Finally, we\'ve improved image optimization when self-hosting. Previously, we recommended you install sharp
for optimizing images on your Next.js server. This recommendation was sometimes missed. With Next.js 15, you no longer need to manually install sharp
— Next.js will use sharp
automatically when using next start
or running with standalone output mode.
To learn more, see our new demo and tutorial video on self-hosting Next.js.
\\nNext.js 15 also introduces support for ESLint 9, following the end-of-life for ESLint 8 on October 5, 2024.
\\nTo ensure a smooth transition, Next.js remain backwards compatible, meaning you can continue using either ESLint 8 or 9.
\\nIf you upgrade to ESLint 9, and we detect that you haven’t yet adopted the new config format, Next.js will automatically apply the ESLINT_USE_FLAT_CONFIG=false
escape hatch to ease migration.
Additionally, deprecated options like —ext
and —ignore-path
will be removed when running next lint
. Please note that ESLint will eventually disallow these older configurations in ESLint 10, so we recommend starting your migration soon.
For more details on these changes, check out the migration guide.
\\nAs part of this update, we’ve also upgraded eslint-plugin-react-hooks
to v5.0.0
, which introduces new rules for React Hooks usage. You can review all changes in the changelog for eslint-plugin-react-hooks@5.0.0.
export const runtime = \\"experimental-edge\\"
in the App Router. Users should now switch to export const runtime = \\"edge\\"
. We’ve added a codemod to perform this (PR)revalidateTag
and revalidatePath
during render will now throw an error (PR)instrumentation.js
and middleware.js
files will now use the vendored React packages (PR)next/dynamic
: the deprecated suspense
prop has been removed and when the component is used in the App Router, it won\'t insert an empty Suspense boundary anymore (PR)worker
module condition will not be applied (PR)outputFileTracingRoot
, outputFileTracingIncludes
and outputFileTracingExcludes
have been upgraded from experimental and are now stable (PR)NEXT_CACHE_HANDLER_PATH
environment variable (PR)priority
attribute (PR)unstable_rethrow
function to rethrow Next.js internal errors in the App Router (PR)unstable_after
can now be used in static pages (PR)next/dynamic
component is used during SSR, the chunk will be prefetched (PR)esmExternals
option is now supported on the App Router (PR)experimental.allowDevelopmentBuild
option can be used to allow NODE_ENV=development
with next build
for debugging purposes (PR)vercel/og
updated with a memory leak fix (PR)msw
for APIs mocking (PR)Next.js is the result of the combined work of over 3,000 individual developers, and our core team at Vercel.\\nThis release was brought to you by:
\\nHuge thanks to @huozhi, @shuding, @wyattjoh, @PaulAsjes, @mcnaveen, @timneutkens, @stipsan, @aktoriukas, @sirTangale, @greatvivek11, @sokra, @anatoliik-lyft, @wbinnssmith, @coltonehrman, @hungdoansy, @kxlow, @ztanner, @manovotny, @leerob, @ryota-murakami, @ijjk, @pnutmath, @feugy, @Jeffrey-Zutt, @wiesson, @eps1lon, @devjiwonchoi, @Ethan-Arrowood, @kenji-webdev, @domdomegg, @samcx, @Jaaneek, @evanwinter, @kdy1, @balazsorban44, @feedthejim, @ForsakenHarmony, @kwonoj, @delbaoliveira, @xiaohanyu, @dvoytenko, @bobaaaaa, @bgw, @gaspar09, @souporserious, @unflxw, @kiner-tang, @Ehren12, @EffectDoplera, @IAmKushagraSharma, @Auxdible, @sean-rallycry, @jeanmax1me, @unstubbable, @NilsJacobsen, @adiguno, @ryan-nauman, @zsh77, @KagamiChan, @steveluscher, @MehfoozurRehman, @vkryachko, @chentsulin, @samijaber, @begalinsaf, @FluxCapacitor2, @lukahartwig, @brianshano, @pavelglac, @styfle, @symant233, @HristovCodes, @karlhorky, @jonluca, @jonathan-ingram, @mknichel, @sopranopillow, @Gomah, @imddc, @notrab, @gabrielrolfsen, @remorses, @AbhiShake1, @agadzik, @rishabhpoddar, @rezamauliadi, @IncognitoTGT, @webtinax, @BunsDev, @nisabmohd, @z0n, @bennettdams, @joeshub, @n1ckoates, @srkirkland, @RiskyMH, @coopbri, @okoyecharles, @diogocapela, @dnhn, @typeofweb, @davidsa03, @imranolas, @lubieowoce, @maxhaomh, @mirasayon, @blvdmitry, @hwangstar156, @lforst, @emmerich, @christian-bromann, @Lsnsh, @datner, @hiro0218, @flybayer, @ianmacartney, @ypessoa, @ryohidaka, @icyJoseph, @Arinji2, @lovell, @nsams, @Nayeem-XTREME, @JamBalaya56562, @Arindam200, @gaojude, @qqww08, @todor0v, @tokkiyaa, @arlyon, @lorensr, @Juneezee, @Sayakie, @IGassmann, @bosconian-dynamics, @phryneas, @akazwz, @atik-persei, @shubh73, @alpedia0, @chogyejin, @notomo, @ArnoldVanN, @dhruv-kaushik, @kevva, @Kahitar, @anay-208, @boris-szl, @devnyxie, @LorisSigrist, @M-YasirGhaffar, @Lada496, @kippmr, @torresgol10, @pkiv, @Netail, @jontewks, @ArnaudFavier, @chrisjstott, @mratlamwala, @mayank1513, @karlkeefer, @kshehadeh, @Marukome0743, @a89529294, @anku255, @KeisukeNagakawa, @andrii-bodnar, @aldosch, @versecafe, @steadily-worked, @cfrank, @QiuranHu, @farsabbutt, @joostmeijles, @saltcod, @archanaagivale30, @crutchcorn, @crebelskydico, @Maaz-Ahmed007, @jophy-ye, @remcohaszing, @JoshuaKGoldberg, @creativoma, @GyoHeon, @SukkaW, @MaxLeiter, @neila-a, @stylessh, @Teddir, @ManuLpz4, @Julian-Louis, @syi0808, @mert-duzgun, @amannn, @MonstraG, @hamirmahal, @tariknh, @Kikobeats, @LichuAcu, @Kuboczoch, @himself65, @Sam-Phillemon9493, @Shruthireddy04, @Hemanshu-Upadhyay, @timfuhrmann, @controversial, @pathliving, @mischnic, @mauroaccornero, @NavidNourani, @allanchau, @ekremkenter, @yurivangeffen, @gnoff, @darthmaim, @gdborton, @Willem-Jaap, @KentoMoriwaki, @TrevorSayre, @marlier, @Luluno01, @xixixao, @domin-mnd, @niketchandivade, @N2D4, @kjugi, @luciancah, @mud-ali, @codeSTACKr, @luojiyin1987, @mehmetozguldev, @ronanru, @tknickman, @joelhooks, @khawajaJunaid, @rubyisrust, @abdull-haseeb, @bewinsnw, @housseindjirdeh, @li-jia-nan, @aralroca, @s-ekai, @ah100101, @jantimon, @jordienr, @iscekic, @Strift, @slimbde, @nauvalazhar, @HughHzyb, @guisehn, @wesbos, @OlyaPolya, @paarthmadan, @AhmedBaset, @dineshh-m, @avdeev, @Bhavya031, @MildTomato, @Bjornnyborg, @amikofalvy, @yosefbeder, @kjac, @woutvanderploeg, @Ocheretovich, @ProchaLu, @luismiramirez, @omahs, @theoludwig, @abhi12299, @sommeeeer, @lumirlumir, @royalfig, @iampoul, @molebox, @txxxxc, @zce, @mamuso, @kahlstrm, @vercel-release-bot, @zhawtof, @PapatMayuri, @PlagueFPS, @IDNK2203, @jericopulvera, @liby, @CannonLock, @timfish, @whatisagi, @none23, @haouvw, @Pyr33x, @SouthLink, @frydj, @CrutchTheClutch, @sleevezip, @r34son, @yunsii, @md-rejoyan-islam, @kartheesan05, @nattui, @KonkenBonken, @weicheng95, @brekk, @Francoscopic, @B33fb0n3, @ImDR, @nurullah, @hdodov, @ebCrypto, @soedirgo, @floriangosse, @Tim-Zj, @raeyoung-kim, @erwannbst, @DerTimonius, @hirotomoyamada, @Develliot, @chandanpasunoori, @vicb, @ankur-dwivedi, @kidonng, @baeharam, @AnaTofuZ, @coderfin, @xugetsu, @alessiomaffeis, @kutsan, @jordyfontoura, @sebmarkbage, @tranvanhieu01012002, @jlbovenzo, @Luk-z, @jaredhan418, @bangseongbeom, @penicillin0, @neoFinch, @DeepakBalaraman, @Manoj-M-S, @Unsleeping, @lonr, @Aerilym, @ytori, @acdlite, @actopas, @n-ii-ma, @adcichowski, @mobeigi, @JohnGemstone, and @jjm2317 for helping!
","description":"Following the announcement of the first Next.js 15 Release Candidate back in May, we’ve been preparing a second Release Candidate based on your feedback. Here’s what we’ve been working on: @next/codemod upgrade: Easily upgrade to the latest Next.js and React versions.\\nTurbopack…","guid":"https://nextjs.org/blog/next-15-rc2","author":null,"authorUrl":null,"authorAvatar":null,"publishedAt":"2024-10-14T16:00:00.488Z","media":[{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Fnext-15-rc2%2Fstatic-route-light.png&w=3840&q=75","type":"photo","width":1720,"height":516},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Fnext-15-rc2%2Fstatic-route-dark.png&w=3840&q=75","type":"photo","width":1720,"height":516}],"categories":null,"attachments":null,"extra":null,"language":null},{"title":"Next.js 11.1","url":"https://nextjs.org/blog/next-11-1","content":"We\'re improving build performance across the entire stack with Next.js 11.1, featuring:
\\nkeep-alive
when pre-rendering.next/image
Improvements: Optional Sharp usage, better support for next export
.Update today by running npm i next@latest
.
The Next.js team works with security researchers and auditors to prevent against vulnerabilities. We are thankful to Gabriel Benmergui from Robinhood for their investigation and discovery of an open redirect with pages/_error.js
and subsequent responsible disclosure.
The reported issue did not directly harm users, but it could allow for phishing attacks by redirecting to an attacker\'s domain from a trusted domain. We\'ve landed a patch in Next.js 11.1 preventing this open redirect from occurring, as well as security regression tests.
\\nFor more details, please read the public CVE. We recommend upgrading to the latest version of Next.js to improve the overall security of your application. For future responsible disclosure of reports, email us at security@vercel.com
.
Note: Next.js applications hosted on Vercel are not affected by this vulnerability (and, therefore, no action is needed for your Next.js apps running on Vercel.
\\nWe\'re working on extensive ES Modules support in Next.js, both as input modules and as an output target. Starting with Next.js 11.1, you can now import npm packages using ES Modules (e.g. \\"type\\": \\"module\\"
in their package.json
) with an experimental flag.
module.exports = {\\n // Prefer loading of ES Modules over CommonJS\\n experimental: { esmExternals: true },\\n};
ES Modules support includes backward compatibility to support the previous import behavior of CommonJS. In Next.js 12, esmExternals: true
will become the default. We recommend trying the new option and leave feedback GitHub Discussions if you have suggestions for improvement.
We\'re working on integrating SWC, a super-fast JavaScript and TypeScript compiler written in Rust, that will replace two toolchains used in Next.js: Babel for individual files and Terser for minifying of output bundles.
\\nAs part of replacing Babel with SWC, we are porting all custom code transformations Next.js uses to SWC transforms written in Rust to maximize performance. For example, tree shaking unused code inside getStaticProps
, getStaticPaths
, and getServerSideProps
.
As part of replacing Terser, we are working on ensuring the SWC minifier has similar output to Terser while massively improving performance and parallelization of minification.
\\nIn early tests, previous code transformations using Babel dropped from ~500ms to ~10ms and code minification from Terser dropped from ~250ms to ~30ms using SWC. Overall, this resulted in twice as fast builds.
\\nWe\'re excited to announce DongYoon Kang, the creator of SWC, and Maia Teegarden, contributor to Parcel, have joined the Next.js team at Vercel to work on improving both next dev
and next build
performance. We will be sharing more results from our SWC adoption in the next release when it\'s made stable.
When using next build
and making numerous HTTP requests, we\'ve improved performance by ~2x on average. For example, if you\'re using getStaticProps
and getStaticPaths
to fetch content from a Headless CMS, you should see noticeably faster builds.
Next.js automatically polyfills node-fetch and now enables HTTP Keep-Alive by default. According to external benchmarks, this should make pre-rendering ~2x faster.
\\nTo disable HTTP Keep-Alive for certain fetch()
calls, you can add the agent option:
import { Agent } from \'https\';\\nconst url = \'<https://example.com>\';\\nconst agent = new Agent({ keepAlive: false });\\nfetch(url, { agent });
To override all fetch()
calls globally, you can use next.config.js
:
module.exports = {\\n httpAgentOptions: {\\n keepAlive: false,\\n },\\n};
Including browser source maps in Next.js applications now has about 70% less performance cost and about 67% less memory cost due to optimizations in webpack asset and source map processing.
\\nThis only affects Next.js applications with productionBrowserSourceMaps: true
in their next.config.js
file. With Next.js 11.1, build times are only increased by 11% when source maps are enabled.
We\'ve also worked with Sentry to increase performance of uploading source maps with the Sentry Next.js plugin.
\\nIn Next.js 11, we introduced built-in ESLint support through next lint
. Since its initial release, we\'ve continued adding rules that help developers fix common mistakes in their applications.
Better accessibility rules are now included by default, preventing issues with ARIA properties that do not match each other and usage of non-existent ARIA attributes. These rules will warn by default.
\\nSpecial thanks to community contributor JeffersonBledsoe for adding these rules.
\\nLinting for common typos in getStaticProps
, getStaticPaths
, and getServerSideProps
will now warn by default. This will help with cases where a small typo causes data fetching to not be called. For example getstaticprops
or getStaticprops
will show a warning.
Special thanks to community contributor kaykdm for creating this rule.
\\nnext/image
Improvements\\n \\n \\n \\n \\nWe\'ve been collecting community feedback about next/image
and the built-in Image Optimization and are excited to share multiple improvements to performance, developer experience, and user experience.
By default, Next.js uses WebAssembly to perform Image Optimization, which offsets the install time of the Next.js package by being significantly smaller and not having a post-install step. With Next.js 11.1, you can optionally install sharp
which optimizes for uncached image generation time with a trade-off of slower installation.
The WebAssembly-based image optimizer has been updated to support ARM chips like Apple M1 with Node.js 16.
\\nThe built-in image optimizer now automatically detects the external image content type based on the content of the response body. This allows Next.js to optimize images hosted on AWS S3 when the response header is Content-Type: application/octet-stream
.
During next dev
static image imports with placeholder=\\"blur\\"
are now automatically lazy-generated, improving dev server startup time for applications with many static image imports:
import Image from \'next/image\';\\nimport author from \'../public/me.png\';\\n \\nexport default function Home() {\\n return (\\n // The placeholder for this image is lazy-generated during development\\n <Image src={author} alt=\\"Picture of the author\\" placeholder=\\"blur\\" />\\n );\\n}
next export
: next/image
now supports using next export
along with any third-party image optimization service. You can configure images.loader: \\"custom\\"
in next.config.js
when you intend to provide the custom loader
prop to next/image
.onLoadingComplete
to next/image
. This allows for registering a callback that is invoked once the image has fully loaded.images.minimumCacheTTL
in next.config.js
to change the default cache TTL for optimized images. When possible, we recommend using static image import
s, as those automatically use the maximum TTL because the image content hash is in the URL.Next.js is the result of the combined work of over 1,700 individual developers, industry partners like Google and Facebook, and our core team.
\\nWe\'re proud to see that community continue to grow. Within the last six months alone, we\'ve seen a 50% increase in Next.js downloads on NPM, from 4.1M to 6.2M and the number of homepages using Next.js in the Alexa top 10,000 has grown 50%.
\\nThis release was brought to you by the contributions of: @abotsi, @adam-cowley, @afbarbaro, @akellbl4, @AndreVarandas, @andys-github, @angeloashmore, @apuyou, @arturmuller, @AryanBeezadhur, @atcastle, @borekb, @brandonchinn178, @breyed, @brijendravarma, @ctbarna, @ctjlewis, @darshkpatel, @delbaoliveira, @destruc7i0n, @devknoll, @enesakar, @enzoferey, @euess, @fabb, @gnbaron, @hiro0218, @housseindjirdeh, @huozhi, @ijjk, @JacobLey, @jameshoward, @jamsinclair, @janicklas-ralph, @jarvelov, @javivelasco, @jaybekster, @JeffersonBledsoe, @jflayhart, @johnrackles, @jviide, @karlsander, @kasipavankumar, @kaykdm, @kdy1, @kylemh, @leerob, @LetItRock, @lsndr, @lucleray, @m-abdelwahab, @mandarons, @markkaylor, @mastoj, @michalbundyra, @michielvangendt, @Munawwar, @mvasilkov, @NickCrews, @NickKelly1, @noahweingand, @noreiller, @nyedidikeke, @omasher, @orta, @pa-rang, @padmaia, @papaponmx, @PaulvdDool, @petermekhaeil, @phocks, @pranavp10, @qwertyforce, @raon0211, @reod, @rishabhpoddar, @roim, @Ryz0nd, @sa3dany, @sachinraja, @samrobbins85, @schoenwaldnils, @schultzp2020, @sedlukha, @sergioalvz, @shibe23, @smitssjors, @sohamsshah, @sokra, @stefanprobst, @stovmascript, @stuymedova, @styfle, @tanys123, @ThangHuuVu, @theostrahlen, @thomasmarshall, @tigger9flow, @timneutkens, @Timvdv, @tmcgann, @tomchen, @UniqueNL, @Vadorequest, @vitalybaev, @yunger7, @zackdotcomputer, @zeekrey
","description":"We\'re improving build performance across the entire stack with Next.js 11.1, featuring: Security Patch: An important update to prevent potential open redirects.\\nES Modules Support: Enable today with an experimental flag.\\nRust-based Tooling: SWC integration to replace JS tooling…","guid":"https://nextjs.org/blog/next-11-1","author":null,"authorUrl":null,"authorAvatar":null,"publishedAt":"2024-09-14T15:28:26.616Z","media":null,"categories":null,"attachments":null,"extra":null,"language":null},{"title":"Next.js 15 RC","url":"https://nextjs.org/blog/next-15-rc","content":"The Next.js 15 Release Candidate (RC) is now available. This early version allows you to test the latest features before the upcoming stable release.
\\nfetch
requests, GET
Route Handlers, and client navigations are no longer cached by defaultnext/after
(Experimental): New API to execute code after a response has finished streamingcreate-next-app
: Updated design and a new flag to enable Turbopack in local developmentTry the Next.js 15 RC today:
\\nnpm install next@rc react@rc react-dom@rc
The Next.js App Router is built on the React canary channel for frameworks, which has allowed developers to use and provide feedback on these new React APIs before the v19 release.
\\nNext.js 15 RC now supports React 19 RC, which includes new features for both the client and server like Actions.
\\nRead the Next.js 15 upgrade guide, the React 19 upgrade guide, and watch the React Conf Keynote to learn more.
\\n\\n\\nNote: Some third party libraries may not be compatible with React 19 yet.
\\n
The React Compiler is a new experimental compiler created by the React team at Meta. The compiler understands your code at a deep level through its understanding of plain JavaScript semantics and the Rules of React, which allows it to add automatic optimizations to your code. The compiler reduces the amount of manual memoization developers have to do through APIs such as useMemo
and useCallback
- making code simpler, easier to maintain, and less error prone.
With Next.js 15, we\'ve added support for the React Compiler.
\\nInstall babel-plugin-react-compiler
:
npm install babel-plugin-react-compiler
Then, add experimental.reactCompiler
option in next.config.js
:
const nextConfig = {\\n experimental: {\\n reactCompiler: true,\\n },\\n};\\n \\nmodule.exports = nextConfig;
Optionally, you can configure the compiler to run in \\"opt-in\\" mode as follows:
\\nconst nextConfig = {\\n experimental: {\\n reactCompiler: {\\n compilationMode: \'annotation\',\\n },\\n },\\n};\\n \\nmodule.exports = nextConfig;
\\n\\nNote: The React Compiler is currently only possible to use in Next.js through a Babel plugin, which could result in slower build times.
\\n
Learn more about the React Compiler, and the available Next.js config options.
\\nNext.js 14.1 made improvements to error messages and hydration errors. Next.js 15 continues to build on those by adding an improved hydration error view. Hydration errors now display the source code of the error with suggestions on how to address the issue.
\\nFor example, this was a previous hydration error message in Next.js 14.1:
\\nNext.js 15 RC has improved this to:
\\nNext.js App Router launched with opinionated caching defaults. These were designed to provide the most performant option by default with the ability to opt out when required.
\\nBased on your feedback, we re-evaluated our caching heuristics and how they would interact with projects like Partial Prerendering (PPR) and with third party libraries using fetch
.
With Next.js 15, we’re changing the caching default for fetch
requests, GET
Route Handlers, and Client Router Cache from cached by default to uncached by default. If you want to retain the previous behavior, you can continue to opt-into caching.
We\'re continuing to improve caching in Next.js in the coming months and we\'ll share more details in the Next.js 15 GA announcement.
\\nfetch
Requests are no longer cached by defaultNext.js uses the Web fetch
API cache option to configure how a server-side fetch request interacts with the framework\'s persistent HTTP cache:
fetch(\'https://...\', { cache: \'force-cache\' | \'no-store\' });
no-store
- fetch a resource from a remote server on every request and do not update the cacheforce-cache
- fetch a resource from the cache (if it exists) or a remote server and update the cacheIn Next.js 14, force-cache
was used by default if a cache
option was not provided, unless a dynamic function or dynamic config option was used.
In Next.js 15, no-store
is used by default if a cache
option is not provided. This means fetch requests will not be cached by default.
You can still opt into caching fetch
requests by:
cache
option to force-cache
in a single fetch
calldynamic
route config option to \'force-static\'
for a single routefetchCache
route config option to \'default-cache\'
to override all fetch
requests in a Layout or Page to use force-cache
unless they explicitly specify their own cache
optionGET
Route Handlers are no longer cached by defaultIn Next 14, Route Handlers that used the GET
HTTP method were cached by default unless they used a dynamic function or dynamic config option. In Next.js 15, GET
functions are not cached by default.
You can still opt into caching using a static route config option such as export dynamic = \'force-static\'
.
Special Route Handlers like sitemap.ts
, opengraph-image.tsx
, and icon.tsx
, and other metadata files remain static by default unless they use dynamic functions or dynamic config options.
In Next.js 14.2.0, we introduced an experimental staleTimes
flag to allow custom configuration of the Router Cache.
In Next.js 15, this flag still remains accessible, but we are changing the default behavior to have a staleTime
of 0
for Page segments. This means that as you navigate around your app, the client will always reflect the latest data from the Page component(s) that become active as part of the navigation. However, there are still important behaviors that remain unchanged:
staleTimes.static
configuration).You can opt into the previous Client Router Cache behavior by setting the following configuration:
\\nconst nextConfig = {\\n experimental: {\\n staleTimes: {\\n dynamic: 30,\\n },\\n },\\n};\\n \\nmodule.exports = nextConfig;
In Next.js 14, we introduced Partial Prerendering (PPR) - an optimization that combines static and dynamic rendering on the same page.
\\nNext.js currently defaults to static rendering unless you use dynamic functions such as cookies()
, headers()
, and uncached data requests. These APIs opt an entire route into dynamic rendering. With PPR, you can wrap any dynamic UI in a Suspense boundary. When a new request comes in, Next.js will immediately serve a static HTML shell, then render and stream the dynamic parts in the same HTTP request.
To allow for incremental adoption, we’ve added an experimental_ppr
route config option for opting specific Layouts and Pages into PPR:
import { Suspense } from \\"react\\"\\nimport { StaticComponent, DynamicComponent } from \\"@/app/ui\\"\\n \\nexport const experimental_ppr = true\\n \\nexport default function Page() {\\n return {\\n <>\\n <StaticComponent />\\n <Suspense fallback={...}>\\n <DynamicComponent />\\n </Suspense>\\n </>\\n };\\n}
To use the new option, you’ll need to set the experimental.ppr
config in your next.config.js
file to \'incremental\'
:
const nextConfig = {\\n experimental: {\\n ppr: \'incremental\',\\n },\\n};\\n \\nmodule.exports = nextConfig;
Once all the segments have PPR enabled, it’ll be considered safe for you to set the ppr
value to true
, and enable it for the entire app and all future routes.
We will share more about our PPR roadmap in our Next.js 15 GA blog post.
\\nLearn more about Partial Prerendering.
\\nnext/after
(Experimental)When processing a user request, the server typically performs tasks directly related to computing the response. However, you may need to perform tasks such as logging, analytics, and other external system synchronization.
\\nSince these tasks are not directly related to the response, the user should not have to wait for them to complete. Deferring the work after responding to the user poses a challenge because serverless functions stop computation immediately after the response is closed.
\\nafter()
is a new experimental API that solves this problem by allowing you to schedule work to be processed after the response has finished streaming, enabling secondary tasks to run without blocking the primary response.
To use it, add experimental.after
to next.config.js
:
const nextConfig = {\\n experimental: {\\n after: true,\\n },\\n};\\n \\nmodule.exports = nextConfig;
Then, import the function in Server Components, Server Actions, Route Handlers, or Middleware.
\\nimport { unstable_after as after } from \'next/server\';\\nimport { log } from \'@/app/utils\';\\n \\nexport default function Layout({ children }) {\\n // Secondary task\\n after(() => {\\n log();\\n });\\n \\n // Primary task\\n return <>{children}</>;\\n}
Learn more about next/after
.
create-next-app
updatesFor Next.js 15, we\'ve updated create-next-app
with a new design.
When running create-next-app
, there is a new prompt asking if you want to enable Turbopack for local development (defaults to No
).
✔ Would you like to use Turbopack for next dev? … No / Yes
The --turbo
flag can be used to enable Turbopack.
npx create-next-app@rc --turbo
To make getting started on a new project even easier, a new --empty
flag has been added to the CLI. This will remove any extraneous files and styles, resulting in a minimal \\"hello world\\" page.
npx create-next-app@rc --empty
Bundling external packages can improve the cold start performance of your application. In the App Router, external packages are bundled by default, and you can opt-out specific packages using the new serverExternalPackages
config option.
In the Pages Router, external packages are not bundled by default, but you can provide a list of packages to bundle using the existing transpilePackages
option. With this configuration option, you need to specify each package.
To unify configuration between App and Pages Router, we’re introducing a new option, bundlePagesRouterDependencies
to match the default automatic bundling of the App Router. You can then use serverExternalPackages
to opt-out specific packages, if needed.
const nextConfig = {\\n // Automatically bundle external packages in the Pages Router:\\n bundlePagesRouterDependencies: true,\\n // Opt specific packages out of bundling for both App and Pages Router:\\n serverExternalPackages: [\'package-name\'],\\n};\\n \\nmodule.exports = nextConfig;
Learn more about optimizing external packages.
\\nsquoosh
in favor of sharp
as an optional dependency (PR)Content-Disposition
to attachment
(PR)src
has leading or trailing spaces (PR)react-server
condition to limit unrecommended react API imports (PR)@next/font
package (PR)font-family
hashing (PR)force-dynamic
will now set a no-store
default to the fetch cache (PR)swcMinify
(PR), missingSuspenseWithCSRBailout
(PR), and outputFileTracing
(PR) behavior by default and remove deprecated options.xml
extension for dynamic sitemap routes and align sitemap URLs between development and production (PR)metadataBase
when hosted on Vercel (PR)optimizePackageImports
(PR)bundlePagesExternals
is now stable and renamed to bundlePagesRouterDependencies
serverComponentsExternalPackages
is now stable and renamed to serverExternalPackages
.env
files by default (PR)@next/env
package (PR)To learn more, check out the upgrade guide.
\\nNext.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.\\nThis release was brought to you by:
\\nHuge thanks to @devjiwonchoi, @ijjk, @Ethan-Arrowood, @sokra, @kenji-webdev, @wbinnssmith, @huozhi, @domdomegg, @samcx, @Jaaneek, @evanwinter, @wyattjoh, @kdy1, @balazsorban44, @feedthejim, @ztanner, @ForsakenHarmony, @kwonoj, @delbaoliveira, @stipsan, @leerob, @shuding, @xiaohanyu, @timneutkens, @dvoytenko, @bobaaaaa, @bgw, @gaspar09, @souporserious, @unflxw, @kiner-tang, @Ehren12, @EffectDoplera, @IAmKushagraSharma, @Auxdible, @sean-rallycry, @Jeffrey-Zutt, @eps1lon, @jeanmax1me, @unstubbable, @NilsJacobsen, @PaulAsjes, @adiguno, @ryan-nauman, @zsh77, @KagamiChan, @steveluscher, @MehfoozurRehman, @vkryachko, @chentsulin, @samijaber, @begalinsaf, @FluxCapacitor2, @lukahartwig, @brianshano, @pavelglac, @styfle, @symant233, @HristovCodes, @karlhorky, @jonluca, @jonathan-ingram, @mknichel, @sopranopillow, @Gomah, @imddc, @notrab, @gabrielrolfsen, @remorses, @AbhiShake1, @agadzik, @ryota-murakami, @rishabhpoddar, @rezamauliadi, @IncognitoTGT, @webtinax, @BunsDev, @nisabmohd, @z0n, @bennettdams, @joeshub, @n1ckoates, @srkirkland, @RiskyMH, @coopbri, @okoyecharles, @diogocapela, @dnhn, @typeofweb, @davidsa03, @imranolas, @lubieowoce, @maxhaomh, @mirasayon, @blvdmitry, @hwangstar156, @lforst, @emmerich, @christian-bromann, @Lsnsh, @datner, @hiro0218, @flybayer, @ianmacartney, @ypessoa, @ryohidaka, @icyJoseph, @Arinji2, @lovell, @nsams, @Nayeem-XTREME, @JamBalaya56562, @Arindam200, @gaojude, @qqww08, @todor0v, @coltonehrman, and @wiesson for helping!
","description":"The Next.js 15 Release Candidate (RC) is now available. This early version allows you to test the latest features before the upcoming stable release. React: Support for the React 19 RC, React Compiler (Experimental), and hydration error improvements\\nCaching: fetch requests, GET…","guid":"https://nextjs.org/blog/next-15-rc","author":null,"authorUrl":null,"authorAvatar":null,"publishedAt":"2024-05-22T16:00:00.343Z","media":[{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Fnext-15-rc%2Fhydration-error-before-light.png&w=3840&q=75","type":"photo","width":1924,"height":1034},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Fnext-15-rc%2Fhydration-error-before-dark.png&w=3840&q=75","type":"photo","width":1924,"height":1034},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Fnext-15-rc%2Fhydration-error-after-light.png&w=3840&q=75","type":"photo","width":1920,"height":1308},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Fnext-15-rc%2Fhydration-error-after-dark.png&w=3840&q=75","type":"photo","width":1920,"height":1308},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Fnext-15-rc%2Fcreate-next-app-light.png&w=3840&q=75","type":"photo","width":2038,"height":1440},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Fnext-15-rc%2Fcreate-next-app-dark.png&w=3840&q=75","type":"photo","width":2038,"height":1440}],"categories":null,"attachments":null,"extra":null,"language":null},{"title":"Next.js 14.2","url":"https://nextjs.org/blog/next-14-2","content":"Next.js 14.2 includes development, production, and caching improvements.
\\nnext dev --turbo
.staleTimes
.Upgrade today or get started with:
\\nnpx create-next-app@latest
Over the past few months, we’ve been working on improving local development performance with Turbopack. In version 14.2, the Turbopack Release Candidate is now available for local development:
\\nnpm
packages used in Next.js applications can compile with Turbopack.We’ve been extensively dogfooding Turbopack with Vercel’s applications. For example, with vercel.com
, a large Next.js app, we\'ve seen:
Turbopack continues to be opt-in and you can try it out with:
\\nnext dev --turbo
We will now be focusing on improving memory usage, implementing persistent caching, and next build --turbo
.
next build
- While Turbopack is not available for builds yet, 74.7% of tests are already passing. You can follow the progress at areweturboyet.com/build.To see a list of supported and unsupported features in Turbopack, please refer to our documentation.
\\nIn addition to bundling improvements with Turbopack, we’ve worked to improve overall build and production performance for all Next.js applications (both Pages and App Router).
\\nWe identified an optimization for the boundary between Server and Client Components that allows for tree-shaking unused exports. For example, importing a single Icon
component from a file that has \\"use client\\"
no longer includes all the other icons from that package. This can largely reduce the production JavaScript bundle size.
Testing this optimization on a popular library like react-aria-components
reduced the final bundle size by -51.3%.
\\n\\nNote: This optimization does not currently work with barrel files. In the meantime, you can use the
\\noptimizePackageImports
config option:\\nnext.config.tsmodule.exports = {\\n experimental: {\\n optimizePackageImports: [\'package-name\'],\\n },\\n};
For extremely large-scale Next.js applications, we noticed out-of-memory crashes (OOMs) during production builds. After investigating user reports and reproductions, we identified the root issue was over-bundling and minification (Next.js created fewer, larger JavaScript files with duplication). We’ve refactored the bundling logic and optimized the compiler for these cases.
\\nOur early tests show that on a minimal Next.js app, memory usage and cache file size decreased from 2.2GB to under 190MB on average.
\\nTo make it easier to debug memory performance, we’ve introduced a --experimental-debug-memory-usage
flag to next build
. Learn more in our documentation.
We updated how CSS is optimized during production Next.js builds by chunking CSS to avoid conflicting styles when you navigate between pages.
\\nThe order and merging of CSS chunks are now defined by the import order. For example, base-button.module.css
will be ordered before page.module.css
:
import styles from \'./base-button.module.css\';\\n \\nexport function BaseButton() {\\n return <button className={styles.primary} />;\\n}
import { BaseButton } from \'./base-button\';\\nimport styles from \'./page.module.css\';\\n \\nexport function Page() {\\n return <BaseButton className={styles.primary} />;\\n}
To maintain the correct CSS order, we recommend:
\\nWe don’t expect this change to negatively impact the majority of applications. However, if you see any unexpected styles when upgrading, please review your CSS import order as per the recommendations in our documentation.
\\nCaching is a critical part of building fast and reliable web applications. When performing mutations, both users and developers expect the cache to be updated to reflect the latest changes. We\'ve been exploring how to improve the Next.js caching experience in the App Router.
\\nstaleTimes
(Experimental)The Client-side Router Cache is a caching layer designed to provide a fast navigation experience by caching visited and prefetched routes on the client.
\\nBased on community feedback, we’ve added an experimental staleTimes
option to allow the client-side router cache invalidation period to be configured.
By default, prefetched routes (using the <Link>
component without the prefetch
prop) will be cached for 30 seconds, and if the prefetch
prop is set to true
, 5 minutes. You can overwrite these default values by defining custom revalidation times in next.config.js
:
const nextConfig = {\\n experimental: {\\n staleTimes: {\\n dynamic: 30,\\n static: 180,\\n },\\n },\\n};\\n \\nmodule.exports = nextConfig;
staleTimes
aims to improve the current experience of users who want more control over caching heuristics, but it is not intended to be the complete solution. In upcoming releases, we will focus on improving the overall caching semantics and providing more flexible solutions.
Learn more about staleTimes
in our documentation.
We are continuing to iterate on on Parallel and Intercepting Routes, now improving the integration with the Client-side Router Cache.
\\nrevalidatePath
or revalidateTag
will revalidate the cache and refresh the visible slots while maintaining the user’s current view.router.refresh
now correctly refreshes visible slots, maintaining the current view.In version 14.1, we started working on improving the readability of error messages and stack traces when running next dev
. This work has continued into 14.2 to now include better error messages, overlay design improvements for both App Router and Pages Router, light and dark mode support, and clearer dev
and build
logs.
For example, React Hydration errors are a common source of confusion in our community. While we made improvements to help users pinpoint the source of hydration mismatches (see below), we\'re working with the React team to improve the underlying error messages and show the file name where the error occurred.
\\nBefore:
\\nAfter:
\\nIn February, the React team announced the upcoming release of React 19. To prepare for React 19, we\'re working on integrating the latest features and improvements into Next.js, and plan on releasing a major version to orchestrate these changes.
\\nNew features like Actions and their related hooks, which have been available within Next.js from the React canary channel, will now all be available for all React applications (including client-only applications). We\'re excited to see wider adoption of these features in the React ecosystem.
\\ninstrumentation.ts
(PR)overrideSrc
prop for next/image
(PR).revalidateReason
argument to getStaticProps
(PR).useSelectedLayoutSegment
compatible with the Pages Router (PR).metadataBase
warnings when absolute URLs don’t need to be resolved (PR).next/dynamic
(PR).unoptimized
prop (PR).images.loaderFile
doesn\'t export a default function (PR)Next.js now has over 1 million monthly active developers. We\'re grateful for the community\'s support and contributions. Join the conversation on GitHub Discussions, Reddit, and Discord.
\\nNext.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.\\nThis release was brought to you by:
\\nHuge thanks to @taishikato, @JesseKoldewijn, @Evavic44, @feugy, @liamlaverty, @dvoytenko, @SukkaW, @wbinnssmith, @rishabhpoddar, @better-salmon, @ziyafenn, @A7med3bdulBaset, @jasonuc, @yossydev, @Prachi-meon, @InfiniteCodeMonkeys, @ForsakenHarmony, @miketimmerman, @kwonoj, @williamli, @gnoff, @jsteele-stripe, @chungweileong94, @WITS, @sogoagain, @junioryono, @eisafaqiri, @yannbolliger, @aramikuto, @rocketman-21, @kenji-webdev, @michaelpeterswa, @Dannymx, @vpaflah, @zeevo, @chrisweb, @stefangeneralao, @tknickman, @Kikobeats, @ubinatus, @code-haseeb, @hmmChase, @byhow, @DanielRivers, @wojtekmaj, @paramoshkinandrew, @OMikkel, @theitaliandev, @oliviertassinari, @Ishaan2053, @Sandeep-Mani, @alyahmedaly, @Lezzio, @devjiwonchoi, @juliusmarminge, @szmazhr, @eddiejaoude, @itz-Me-Pj, @AndersDJohnson, @gentamura, @tills13, @dijonmusters, @SaiGanesh21, @vordgi, @ryota-murakami, @tszhong0411, @officialrajdeepsingh, @alexpuertasr, @AkifumiSato, @Jonas-PFX, @icyJoseph, @florian-lp, @pbzona, @erfanium, @remcohaszing, @bernardobelchior, @willashe, @kevinmitch14, @smakosh, @mnjongerius, @asobirov, @theoholl, @suu3, @ArianHamdi, @adrianha, @Sina-Abf, @kuzeykose, @meenie, @nphmuller, @javivelasco, @belgattitude, @Svetoslav99, @johnslemmer, @colbyfayock, @mehranmf31, @m-nakamura145, @ryo8000, @aryaemami59, @bestlyg, @jinsoul75, @petrovmiroslav, @nattui, @zhuyedev, @dongwonnn, @nhducit, @flotwig, @Schmavery, @abhinaypandey02, @rvetere, @coffeecupjapan, @cjimmy, @Soheiljafarnejad, @jantimon, @zengspr, @wesbos, @neomad1337, @MaxLeiter, and @devr77 for helping!
","description":"Next.js 14.2 includes development, production, and caching improvements. Turbopack for Development (Release Candidate): 99.8% tests passing for next dev --turbo.\\nBuild and Production Improvements: Reduced build memory usage and CSS optimizations.\\nCaching Improvements: Configurab…","guid":"https://nextjs.org/blog/next-14-2","author":null,"authorUrl":null,"authorAvatar":null,"publishedAt":"2024-04-10T16:00:00.948Z","media":[{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Fnext-14-2%2Ferror-overlay-before.png&w=2048&q=75","type":"photo","width":1015,"height":881},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Fnext-14-2%2Ferror-overlay-before.png&w=2048&q=75","type":"photo","width":1015,"height":881},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Fnext-14-2%2Ferror-overlay-after.png&w=2048&q=75","type":"photo","width":1021,"height":569},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Fnext-14-2%2Ferror-overlay-after.png&w=2048&q=75","type":"photo","width":1021,"height":569},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Fnext-14-2%2Fone-million-light.png&w=1200&q=75","type":"photo","width":600,"height":337.5},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Fnext-14-2%2Fone-million-dark.png&w=1200&q=75","type":"photo","width":600,"height":337.5}],"categories":null,"attachments":null,"extra":null,"language":null},{"title":"Next.js 14.1","url":"https://nextjs.org/blog/next-14-1","content":"Next.js 14.1 includes developer experience improvements including:
\\nnext dev --turbo
pushState
and replaceState
supportnext/image
Improvements: <picture>
, art direction, and dark mode supportUpgrade today or get started with:
\\nnpx create-next-app@latest
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:
\\nWith 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:
\\nmodule.exports = {\\n cacheHandler: require.resolve(\'./cache-handler.js\'),\\n cacheMaxMemorySize: 0, // disable default in-memory caching\\n};
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.
\\nFor 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.
We\'re continuing to focus on the reliability and performance of local Next.js development:
\\nWe plan to stabilize next dev --turbo
in an upcoming release with it still being opt-in.
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.
\\nWe 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.
\\nFor vercel.com
, a large Next.js application, we\'ve seen:
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.
\\nTurbopack currently has in-memory caching, which improves incremental compilation times for Fast Refresh.
\\nHowever, 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.
\\nWe 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
.
webpack-internal
now properly display the source code of the error and the affected file.metadata
from a Client Component.For example, this was a previous error message:
\\nNext.js 14.1 has improved this to:
\\nwindow.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.
\\n\'use client\';\\n \\nimport { useSearchParams } from \'next/navigation\';\\n \\nexport default function SortProducts() {\\n const searchParams = useSearchParams();\\n \\n function updateSorting(sortOrder: string) {\\n const params = new URLSearchParams(searchParams.toString());\\n params.set(\'sort\', sortOrder);\\n window.history.pushState(null, \'\', `?${params.toString()}`);\\n }\\n \\n return (\\n <>\\n <button onClick={() => updateSorting(\'asc\')}>Sort Ascending</button>\\n <button onClick={() => updateSorting(\'desc\')}>Sort Descending</button>\\n </>\\n );\\n}
Learn more about using the native History API with Next.js.
\\nFor 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:
GET / 200 in 48ms\\n ✓ Compiled /fetch-cache in 117ms\\n GET /fetch-cache 200 in 165ms\\n │ GET https://api.vercel.app/products/1 200 in 14ms (cache: HIT)\\n ✓ Compiled /fetch-no-store in 150ms\\n GET /fetch-no-store 200 in 548ms\\n │ GET https://api.vercel.app/products/1 200 in 345ms (cache: SKIP)\\n │ │ Cache missed reason: (cache: no-store)
This can be enabled through next.config.js
:
module.exports = {\\n logging: {\\n fetches: {\\n fullUrl: true,\\n },\\n },\\n};
next/image
support for <picture>
and Art DirectionThe Next.js Image component now supports more advanced use cases through getImageProps()
(stable) which don\'t require using <Image>
directly. This includes:
background-image
or image-set
context.drawImage()
or new Image()
<picture>
media queries to implement Art Direction or Light/Dark Mode imagesimport { getImageProps } from \'next/image\';\\n \\nexport default function Page() {\\n const common = { alt: \'Hero\', width: 800, height: 400 };\\n const {\\n props: { srcSet: dark },\\n } = getImageProps({ ...common, src: \'/dark.png\' });\\n const {\\n props: { srcSet: light, ...rest },\\n } = getImageProps({ ...common, src: \'/light.png\' });\\n \\n return (\\n <picture>\\n <source media=\\"(prefers-color-scheme: dark)\\" srcSet={dark} />\\n <source media=\\"(prefers-color-scheme: light)\\" srcSet={light} />\\n <img {...rest} />\\n </picture>\\n );\\n}
Learn more about getImageProps()
.
In Next.js 14.1, we\'ve made 20 improvements to Parallel & Intercepted Routes.
\\nFor 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.
\\n/photo/123
route, masks the URL, and overlays it over /feed
.Learn more about Parallel & Intercepted Routes or view an example.
\\nSince 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.
\\n<GoogleAnalytics />
component to next/third-parties
(Docs)create-next-app
is now smaller and faster to install (PR)global-error
(PR)redirect
now respects basePath
when used in a server action (PR)next/script
and beforeInteractive
usage with App Router (PR)@aws-sdk
and lodash
for faster route startup (PR)next dev
and next/font
(PR)notFound
errors past a segment\'s error boundary (PR)revalidate
value is passed (PR)basePath
(PR)basePath
config (PR)revalidatePath
(PR)@children
slots with parallel routes (PR)next build
summary (PR)rewrites
with an intercepted route (PR)useSearchParams
without Suspense
(PR)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.
\\nThis release was brought to you by:
\\nAnd 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.
","description":"Next.js 14.1 includes developer experience improvements including: Improved Self-Hosting: New documentation and custom cache handler\\nTurbopack Improvements: 5,600 tests passing for next dev --turbo\\nDX Improvements: Improved error messages, pushState and replaceState support\\nPara…","guid":"https://nextjs.org/blog/next-14-1","author":null,"authorUrl":null,"authorAvatar":null,"publishedAt":"2024-01-17T16:00:00.464Z","media":[{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Fnext-14-1%2Ferror-before.png&w=3840&q=75","type":"photo","width":1034,"height":394},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Fnext-14-1%2Ferror-before.png&w=3840&q=75","type":"photo","width":1034,"height":394},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Fnext-14-1%2Ferror-after.png&w=3840&q=75","type":"photo","width":1043,"height":482},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Fnext-14-1%2Ferror-after.png&w=3840&q=75","type":"photo","width":1043,"height":482}],"categories":null,"attachments":null,"extra":null,"language":null},{"title":"Next.js 14","url":"https://nextjs.org/blog/next-14","content":"As we announced at Next.js Conf, Next.js 14 is our most focused release with:
\\nUpgrade today or get started with:
\\nnpx create-next-app@latest
Since Next.js 13, we\'ve been working to improve local development performance in Next.js in both the Pages and App Router.
\\nPreviously, we were rewriting next dev
and other parts of Next.js to support this effort. We have since changed our approach to be more incremental. This means our Rust-based compiler will reach stability soon, as we\'ve refocused on supporting all Next.js features first.
5,000 integration tests for next dev
are now passing with Turbopack, our underlying Rust engine. These tests include 7 years of bug fixes and reproductions.
While testing on vercel.com
, a large Next.js application, we\'ve seen:
This benchmark is a practical result of performance improvements you should expect with a large application (and large module graph). With 90% of tests for next dev
now passing, you should see faster and more reliable performance consistently when using next dev --turbo
.
Once we hit 100% of tests passing, we\'ll move Turbopack to stable in an upcoming minor release. We\'ll also continue to support using webpack for custom configurations and ecosystem plugins.
\\nYou can follow the percentage of tests passing at areweturboyet.com.
\\nNext.js 9 introduced API Routes—a way to quickly build backend endpoints alongside your frontend code.
\\nFor example, you would create a new file in the api/
directory:
import type { NextApiRequest, NextApiResponse } from \'next\';\\n \\nexport default async function handler(\\n req: NextApiRequest,\\n res: NextApiResponse,\\n) {\\n const data = req.body;\\n const id = await createItem(data);\\n res.status(200).json({ id });\\n}
Then, on the client-side, you could use React and an event handler like onSubmit
to make a fetch
to your API Route.
import { FormEvent } from \'react\';\\n \\nexport default function Page() {\\n async function onSubmit(event: FormEvent<HTMLFormElement>) {\\n event.preventDefault();\\n \\n const formData = new FormData(event.currentTarget);\\n const response = await fetch(\'/api/submit\', {\\n method: \'POST\',\\n body: formData,\\n });\\n \\n // Handle response if necessary\\n const data = await response.json();\\n // ...\\n }\\n \\n return (\\n <form onSubmit={onSubmit}>\\n <input type=\\"text\\" name=\\"name\\" />\\n <button type=\\"submit\\">Submit</button>\\n </form>\\n );\\n}
Now with Next.js 14, we want to simplify the developer experience of authoring data mutations. Further, we want to improve the user experience when the user has a slow network connection, or when submitting a form from a lower-powered device.
\\nWhat if you didn\'t need to manually create an API Route? Instead, you could define a function that runs securely on the server, called directly from your React components.
\\nThe App Router is built on the React canary
channel, which is stable for frameworks to adopt new features. As of v14, Next.js has upgraded to the latest React canary
, which includes stable Server Actions.
The previous example from the Pages Router can be simplified to one file:
\\nexport default function Page() {\\n async function create(formData: FormData) {\\n \'use server\';\\n const id = await createItem(formData);\\n }\\n \\n return (\\n <form action={create}>\\n <input type=\\"text\\" name=\\"name\\" />\\n <button type=\\"submit\\">Submit</button>\\n </form>\\n );\\n}
Server Actions should feel familiar for any developers who have previously used server-centric frameworks in the past. It\'s built on web fundamentals like forms and the FormData Web API.
\\nWhile using Server Actions through a form is helpful for progressive enhancement, it is not a requirement. You can also call them directly as a function, without a form. When using TypeScript, this gives you full end-to-end type-safety between the client and server.
\\nMutating data, re-rendering the page, or redirecting can happen in one network roundtrip, ensuring the correct data is displayed on the client, even if the upstream provider is slow. Further, you can compose and reuse different actions, including many different actions in the same route.
\\nServer Actions are deeply integrated into the entire App Router model. You can:
\\nrevalidatePath()
or revalidateTag()
redirect()
cookies()
useOptimistic()
useFormState()
useFormStatus()
Learn more about Forms and Mutations with Server Actions or about the security model and best practices for Server Components and Server Actions.
\\nWe\'d like to share a preview of Partial Prerendering — a compiler optimization for dynamic content with a fast initial static response — that we\'re working on for Next.js.
\\nPartial Prerendering builds on a decade of research and development into server-side rendering (SSR), static-site generation (SSG), and incremental static revalidation (ISR).
\\nWe\'ve heard your feedback. There\'s currently too many runtimes, configuration options, and rendering methods to have to consider. You want the speed and reliability of static, while also supporting fully dynamic, personalized responses.
\\nHaving great performance globally and personalization shouldn\'t come at the cost of complexity.
\\nOur challenge was to create a better developer experience, simplifying the existing model without introducing new APIs for developers to learn. While partial caching of server-side content has existed, these approaches still need to meet the developer experience and composability goals we aim for.
\\nPartial Prerendering requires no new APIs to learn.
\\nPartial Prerendering is defined by your Suspense boundaries. Here\'s how it works. Consider the following ecommerce page:
\\nexport default function Page() {\\n return (\\n <main>\\n <header>\\n <h1>My Store</h1>\\n <Suspense fallback={<CartSkeleton />}>\\n <ShoppingCart />\\n </Suspense>\\n </header>\\n <Banner />\\n <Suspense fallback={<ProductListSkeleton />}>\\n <Recommendations />\\n </Suspense>\\n <NewProducts />\\n </main>\\n );\\n}
With Partial Prerendering enabled, this page generates a static shell based on your <Suspense />
boundaries. The fallback
from React Suspense is prerendered.
Suspense fallbacks in the shell are then replaced with dynamic components, like reading cookies to determine the cart, or showing a banner based on the user.
\\nWhen a request is made, the static HTML shell is immediately served:
\\n<main>\\n <header>\\n <h1>My Store</h1>\\n <div class=\\"cart-skeleton\\">\\n <!-- Hole --\x3e\\n </div>\\n </header>\\n <div class=\\"banner\\" />\\n <div class=\\"product-list-skeleton\\">\\n <!-- Hole --\x3e\\n </div>\\n <section class=\\"new-products\\" />\\n</main>
Since <ShoppingCart />
reads from cookies
to look at the user session, this component is then streamed in as part of the same HTTP request as the static shell. There are no extra network roundtrips needed.
import { cookies } from \'next/headers\'\\n \\nexport default function ShoppingCart() {\\n const cookieStore = cookies()\\n const session = cookieStore.get(\'session\')\\n return ...\\n}
To have the most granular static shell, this may require adding additional Suspense boundaries. However, if you\'re already using loading.js
today, this is an implicit Suspense boundary, so no changes would be required to generate the static shell.
Partial prerendering is under active development. We\'ll be sharing more updates in an upcoming minor release.
\\nBefore your page content can be streamed from the server, there\'s important metadata about the viewport, color scheme, and theme that need to be sent to the browser first.
\\nEnsuring these meta
tags are sent with the initial page content helps a smooth user experience, preventing the page from flickering by changing the theme color, or shifting layout due to viewport changes.
In Next.js 14, we\'ve decoupled blocking and non-blocking metadata. Only a small subset of metadata options are blocking, and we want to ensure non-blocking metadata will not prevent a partially prerendered page from serving the static shell.
\\nThe following metadata options are now deprecated and will be removed from metadata
in a future major version:
viewport
: Sets the initial zoom and other properties of the viewportcolorScheme
: Sets the support modes (light/dark) for the viewportthemeColor
: Sets the color the chrome around the viewport should render withStarting with Next.js 14, there are new options viewport
and generateViewport
to replace these options. All other metadata
options remain the same.
You can start adopting these new APIs today. The existing metadata
options will continue to work.
Today we\'re releasing a brand new, free course on Next.js Learn. This course teaches:
\\nNext.js Learn has taught millions of developers about the foundations of the framework, and we can\'t wait to hear your feedback on our new addition. Head to nextjs.org/learn to take the course.
\\n18.17
next-swc
build (PR)@next/font
in favor of next/font
(Codemod)ImageResponse
import from next/server
to next/og
(Codemod)next export
command has been removed in favor of output: \'export\'
config (Docs)onLoadingComplete
for next/image
is deprecated in favor of onLoad
domains
for next/image
is deprecated in favor of remotePatterns
fetch
caching can be enabled (Docs)create-next-app
applicationedge
runtime in developmentNext.js is the result of the combined work of over 2,900 individual developers, industry partners like Google and Meta, and our core team at Vercel. Join the community on GitHub Discussions, Reddit, and Discord.
\\nThis release was brought to you by:
\\nAnd the contributions of: @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, and @zlrlyy
","description":"As we announced at Next.js Conf, Next.js 14 is our most focused release with: Turbopack: 5,000 tests passing for App & Pages Router\\n53% faster local server startup\\n94% faster code updates with Fast Refresh\\nServer Actions (Stable): Progressively enhanced mutations\\nIntegrated…","guid":"https://nextjs.org/blog/next-14","author":null,"authorUrl":null,"authorAvatar":null,"publishedAt":"2023-10-25T16:00:00.741Z","media":null,"categories":null,"attachments":null,"extra":null,"language":null},{"title":"Next.js 13.5","url":"https://nextjs.org/blog/next-13-5","content":"Next.js 13.5 improves local dev performance and reliability with:
\\nnext start
next/image
Improvements: <picture>
, art direction, and dark mode supportUpgrade today and register for Next.js Conf on Oct 26:
\\nnpm i next@latest react@latest react-dom@latest eslint-config-next@latest
We\'re excited to see the continued adoption of the App Router, now growing 80% MoM when looking at the top 10 million origins crawled by the HTTP Archive.
\\nSince Next.js 13.4, our focus has been on improving performance and reliability for App Router applications. Comparing 13.4 to 13.5, we\'ve seen the following improvements on a new application:
\\nWe were able to achieve this performance increase through optimizations like:
\\nNext.js user Lattice reported between 87-92% faster compilation in their testing.
\\nWhile we continue to iterate and improve our current bundler performance, we\'re also working on Turbopack (Beta) in parallel to further increase performance. With 13.5, next dev --turbo
now supports more features.
We\'ve made an exciting breakthrough to optimize package imports, improving both local dev performance and production cold starts, when using large icon or component libraries or other dependencies that re-export hundreds or thousands of modules.
\\nPreviously, we added support for modularizeImports
, enabling you to configure how imports should resolve when using these libraries. In 13.5, we have superseeded this option with optimizePackageImports
, which doesn\'t require you to specify the mapping of imports, but instead will automatically optimize imports for you.
Libraries like @mui/icons-material
, @mui/material
, date-fns
, lodash
, lodash-es
, ramda
, react-bootstrap
, @headlessui/react
,@heroicons/react
, and lucide-react
are now automatically optimized, only loading the modules you are actually using, while still giving you the convenience of writing import
statements with many named exports.
View the PR or learn more about optimizePackageImports
in our documentation.
next/image
ImprovementsBased on community feedback, we\'ve added a new experimental function unstable_getImgProps()
to support advanced use cases without using the <Image>
component directly, including:
background-image
or image-set
context.drawImage()
or new Image()
<picture>
media queries to implement Art Direction or Light/Dark Mode imagesimport { unstable_getImgProps as getImgProps } from \'next/image\';\\n \\nexport default function Page() {\\n const common = { alt: \'Hero\', width: 800, height: 400 };\\n const {\\n props: { srcSet: dark },\\n } = getImgProps({ ...common, src: \'/dark.png\' });\\n const {\\n props: { srcSet: light, ...rest },\\n } = getImgProps({ ...common, src: \'/light.png\' });\\n \\n return (\\n <picture>\\n <source media=\\"(prefers-color-scheme: dark)\\" srcSet={dark} />\\n <source media=\\"(prefers-color-scheme: light)\\" srcSet={light} />\\n <img {...rest} />\\n </picture>\\n );\\n}
Additionally, the placeholder
prop now supports providing arbitrary data:image/
for placeholder images that shouldn\'t be blurred (demo).
Learn more about next/image
in our documentation.
Since 13.4.0
, we\'ve fixed over 438 bugs and made various improvements including:
useParams
and useSearchParams
from next/navigation
now work in the Pages Router for incremental adoptionscroll: false
on router.push
/ router.replace
scroll={false}
on next/link
next dev --experimental-https
cookies().has()
(Docs)redirect()
in Server Actionsbunx create-next-app
(Docs)cookies()
and headers()
are now supported inside Middlewaresummary_large_image
in Twitter cardsRedirectType
is now exported from next/navigation
next start
to handle 1062% more requests/secondnext dev
output (PR)redirect()
now push into the history stack instead of replacing the current entry to ensure the back button worksno-cache, no-store
cache-control
header to prevent browser cachingscroll-behavior: smooth
for hash url changesArray.prototype.at
in all browsersnext dev
cache when handling multiple parallel requestsfetch
output in console now shows requests that skipped cache with cache: SKIP
usePathname
now properly strips basePath
next/image
now properly preloads images in App Routernot-found
no longer renders the root layout twiceNextRequest
can now be cloned (i.e new NextRequest(request)
)app/children/page.tsx
now properly works for literal /children
routesnonce
for preinitialized scriptsredirect
from next/navigation
now supports basePath
process.env
not being available during rendering in output: \'standalone\'
modefallback: false
with dynamic route segments previously causing hanging requestssignal
was passed to revalidate requests, causing them to fail when the request was already abortedfetch
polling on 404 page in favor of websocket events, preventing unnecessary reloads when running next dev
performance.measure
no longer can cause a hydration mismatchpages/_app
ImageResponse
now extends Response
for improved type checking (PR)pages
is no longer shown when there is no pages
output in next build
skipTrailingSlashRedirect
being ignored in <Link>
Next.js is the result of the combined work of over 2,800 individual developers, industry partners like Google and Meta, and our core team at Vercel. Join the community on GitHub Discussions, Reddit, and Discord.
\\nThis release was brought to you by:
\\nAnd the contributions of: @opnay, @vinaykulk621, @goguda, @coreyleelarson, @bencmbrook, @cramforce, @williamli, @stefanprobst, @feugy, @Kikobeats, @dvoytenko, @MaxLeiter, @devjiwonchoi, @lacymorrow, @kylemcd, @tibi1220, @iamarpitpatidar, @pythagoras-yamamoto, @alexkirsz, @jsteele-stripe, @tknickman, @gaojude, @janicklas-ralph, @ericfennis, @JohnAdib, @MiLk, @delbaoliveira, @leerob, @LuudJanssen, @lucasconstantino, @davecarlson, @colinhacks, @jantimon, @Banbarashik, @ForsakenHarmony, @arturbien, @gnoff, @hsrvms, @DuCanhGH, @tim-hanssen, @Aryan9592, @rishabhpoddar, @Lantianyou, @joulev, @AkifumiSato, @trigaten, @HurSungYun, @DevLab2425, @SukkaW, @daniel-web-developer, @ky1ejs, @wyattjoh, @ShaunFerris, @syedtaqi95, @Heidar-An, @Jeffrey-Zutt, @Ryan-Dia, @steppefox, @hiro0218, @rjsdnql123, @fgiuliani, @steven-tey, @AntoineBourin, @adamrhunter, @darshanjain-entrepreneur, @s0h311, @djreillo, @dijonmusters, @cassidoo, @anonrig, @gfgabrielfranca, @Bitbbot, @BrennanColberg, @Nick-Mazuk, @thomasballinger, @lucgagan, @nroland013, @SonMooSans, @jenewland1999, @thorwebdev, @jyunhanlin, @Gnadhi, @yagogmaisp, @carlos-menezes, @ryo-manba, @vamcs, @matepapp, @SleeplessOne1917, @ecklf, @karlhorky, @starunaway, @FernandVEYRIER, @Terro216, @anthonyshew, @suhaotian, @simonswiss, @feikerwu, @lubakravche, @masnormen, @bottxiang, @mhmdrioaf, @tyler-lutz, @vincenthongzy, @yigithanyucedag, @doinki, @danger-ahead, @bre30kra69cs, @Yash-Singh1, @krmeda, @bigyanse, @2-NOW, @Mingyu-Song, @morganfeeney, @aralroca, @nickmccurdy, @adamjmcgrath, @angel1254mc, @cxa, @ibash, @mohanraj-r, @kevinmitch14, @iaurg, @steebchen, @Cow258, @charlesbdudley, @tyhopp, @Drblessing, @milovangudelj, @jacobsfletch, @JoshuaKGoldberg, @zignis, @ChristianIvicevic, @mrxbox98, @oliviertassinari, @fsansalvadore, @tvthatsme, @dvakatsiienko, @brunoeduardodev, @sonam-serchan, @vicsantizo, @leodr, @wiscaksono, @hustLer2k, @joshuabaker, @shozibabbas, @omarhoumz, @jamespearson, @tristndev, @AldeonMoriak, @manovotny, @mirismaili, @SuttonJack, @jeremydouglas, @JanCizmar, @mltsy, @WilderDev, @Guilleo03, @Willem-Jaap, @escwxyz, @wiredacorn, @Ethan-Arrowood, @BaffinLee, @greatSumini, @ciruz, @kijikunnn, @DustinsCode, @riqwan, @joostdecock, @nikolovlazar, @Bowens20832, @JohnAlbin, @gidgudgod, @maxproske, @dunklesToast, @yyuemii, @mPaella, @mknichel, @niko20, @mkcy3, @valentinpolitov, @smaeda-ks, @keyz, @Schniz, @koba04, @jiwooIncludeJeong, @ethanmick, @didemkkaslan, @itsmingjie, @v1k1, @thepatrick00, @taylorbryant, @kvnang, @alainkaiser, @simPod, @svarunid, @pauek, @lycuid, @MarkAtOmniux, @darshkpatel, @johnta0, @devagrawal09, @ibrahemid, @JesseKoldewijn, @javivelasco, @05lazy, @alexanderbluhm, @Fonger, @souporserious, @DevEsteves, @sanjaiyan-dev, @g12i, @cesarkohl, @josh, @li-jia-nan, @gabschne, @akd-io, @runjuu, @jocarrd, @nnnnoel, @ferdingler, and @ikryvorotenko
","description":"Next.js 13.5 improves local dev performance and reliability with: 22% faster local server startup: Iterate faster with the App & Pages Router\\n29% faster HMR (Fast Refresh): For faster iterations when saving changes\\n40% less memory usage: Measured when running next start\\nOptimize…","guid":"https://nextjs.org/blog/next-13-5","author":null,"authorUrl":null,"authorAvatar":null,"publishedAt":"2023-09-18T16:00:00.542Z","media":[{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Fnext-13-5%2Fcrux-light.png&w=3840&q=75","type":"photo","width":1712,"height":788},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Fnext-13-5%2Fcrux.png&w=3840&q=75","type":"photo","width":1712,"height":788}],"categories":null,"attachments":null,"extra":null,"language":null},{"title":"Next.js App Router Update","url":"https://nextjs.org/blog/june-2023-update","content":"The App Router represents a new foundation for the future of Next.js, but we recognize there are opportunities to make the experience better. We\'d like to give an update on what our current priorities are.
\\nFor the upcoming releases of Next.js, we are focusing on the following areas:
\\nFirst, it\'s helpful to provide some context on how the App Router has been designed.
\\nAs we saw increased adoption and larger scale applications being built with Next.js, we received feedback from the community and identified areas where we started to reach the limits of the Pages Router.
\\nMost notably, the Next.js Pages Router was not designed for streaming, a cornerstone primitive in modern React, that helps us address the limitations we were facing and realize our long-term vision for Next.js.
\\nMaking streaming-friendly framework APIs for data fetching, asset loading, and page metadata, as well as taking advantage of React\'s newer primitives required large changes to the core architecture of Next.js.
\\nWe took the opportunity to build on top of the latest React concurrent features, like Server Components, Suspense, and more, which have been designed for streaming architectures.
\\nWe didn\'t want our community to have to rebuild their entire applications from the ground up to update to the latest version of Next.js. We believe incremental adoption is the best strategy for evolving applications over time.
\\nWe are exploring further opportunities to make incremental adoption even easier.
\\nWe began building the Next.js App Router over a year ago and have been steadily releasing new features and improvements since then.
\\nMarking stability signaled to the community that the core API was settled and would not go through major breaking changes that would require rewrites.
\\nSince then, we\'ve received lots of valuable feedback and increased adoption has inevitably revealed bugs and opportunities for further improvement.
\\nWe want you to know that we are not yet satisfied with the experience of using the App Router and it is our top priority moving forward. So, let\'s talk about the work we\'re doing to make this experience better.
\\nOver the coming months, we\'re focused on three aspects of performance: local iteration speed, production build times, and serverless performance.
\\nAs Next.js has matured, and the size of applications built with it have grown, we\'ve slowly and incrementally been replacing pieces of its underlying architecture with faster, more scalable tools.
\\nMigration Progress: We started with replacing Babel (compilation) and Terser (minification) with SWC. This has helped improve local iteration speeds and production build times.
\\nLong-term Investment: Keeping great Fast Refresh performance regardless of an applications size means making Next.js operate as incremental as possible during local development, by only bundling and compiling code as needed.
\\nThis is why we\'re currently working on replacing webpack (bundling) with Turbopack, which is built on a low-level incremental computation engine that enables caching down to the level of individual functions.
\\nNext.js applications that move to Turbopack will see sustained improvements in Fast Refresh speed even as they grow in size.
\\nIn the past few months, the Turbo team has been focused on improving Turbopack performance and support for all Next.js features and App Router APIs.
\\nTurbopack is currently available in beta (next dev --turbo
).
Improving Today\'s Architecture: In addition to investing in the future, we are continuing to make performance improvements to our existing webpack architecture.
\\nFor certain Next.js applications, especially those refreshing thousands of modules, we have seen reports of flakiness with local development and Fast Refresh. We\'re working to improve performance and reliability here. For example, we recently added in pre-configured settings (modularizeImports
) to handle large icon libraries that might accidentally force thousands of modules to reload on every request.
We are also working on production builds with Turbopack (next build --turbo
) and have started to land the first pieces of this work. Expect more updates on this in the coming releases.
Finally, on Vercel, we\'re working to optimize the performance and memory usage of Vercel Functions defined through Next.js application code, ensuring minimal cold starts while retaining the benefits of a scalable serverless architecture. This work has resulted in new tracing capabilities (experimental) in Next.js and early explorations into server-side developer tools.
\\nThe Pages Router has been around for six years now. The release of the App Router meant the introduction of new APIs which are still young, with just six months of usage. We\'ve come a long way in a short amount of time, but there are still opportunities to improve as we learn more from our community and how they\'re using it.
\\nWe appreciate the community\'s willingness to eagerly adopt the App Router and provide feedback. There\'s been a number of bug reports we\'re investigating and we\'re thankful for the minimal reproductions you have created to help isolate issues and verify fixes.
\\nSince 13.4, we\'ve already patched a number of high impact bugs around stability that are available in the latest patch release (13.4.7
). We will be continuing to focus on performance and stability with high intensity.
While we believe the new features of the App Router and modern React are powerful, they also require additional education and documentation to help teach these new concepts.
\\nWe\'ve been working over the past year to re-write the Next.js documentation from scratch. This work is now live on nextjs.org/docs. We\'d like to highlight some important pieces:
\\n/learn
teaching the App Router) and real world codebase examples (including a rewrite of Next.js Commerce).We\'ll be releasing new content in the documentation, on Twitter, YouTube, and more.
\\nWe\'ve also heard your feedback about the education around new React features that are available in the Next.js App Router.
\\nServer Components: It\'s important to note that features like Server Components and conventions like the \\"use client\\"
directive are not Next.js specific, but a larger part of the React ecosystem.
Our team, our partners at Meta, and other independent contributors are working to provide more education around these topics. It\'s early days for these concepts, but we\'re confident in the React ecosystem and continued education.
\\nClient Components: With the recent conversation around Server Components, it\'s important to note the client components are not a de-optimization. The client is a valid part of the React model and is not going away.
\\nYou can think of client components as the existing Next.js ecosystem today, where your favorite libraries and tools continue to work. For example, a common question we\'ve seen is whether \\"use client\\"
needs to be added to every single file to make it a client component. This is not necessary, but we understand these concepts are new and will take time to learn. You only need to mark the top level boundary where you code moves between the server to the client. This architecture allows you to interweave server and client components together.
Growing third-party ecosystem: In addition to education, the ecosystem around React\'s newer features is still growing. For example, Panda CSS, a CSS-in-JS library from the makers of Chakra UI, just announced support for React Server Components.
\\nServer Actions (Alpha): Server Actions enable server-side data mutations, reduced client-side JavaScript, and progressively enhanced forms. We do not recommend using Server Actions in production yet. We appreciate early feedback from alpha testers helping us shape the future of this feature.
\\nWe\'re thankful many of you have chosen to learn and build with Next.js.
\\nOur focus on performance, stability, and developer experience will be reflected in the upcoming releases of Next.js. We want using Next.js to be delightful—and to make you (and your team) more productive.
\\nAs always, we greatly appreciate your feedback. If you are experiencing any issues with Next.js, please open an issue, or start a new discussion, and we will investigate.
","description":"The App Router represents a new foundation for the future of Next.js, but we recognize there are opportunities to make the experience better. We\'d like to give an update on what our current priorities are. For the upcoming releases of Next.js, we are focusing on the following…","guid":"https://nextjs.org/blog/june-2023-update","author":null,"authorUrl":null,"authorAvatar":null,"publishedAt":"2023-06-21T16:00:00.672Z","media":null,"categories":null,"attachments":null,"extra":null,"language":null},{"title":"Next.js 13.4","url":"https://nextjs.org/blog/next-13-4","content":"Next.js 13.4 is a foundational release, marking stability for the App Router:
\\nSince the release of Next.js 13 six months ago, we\'ve been focused on building the foundations for the future of Next.js—App Router—in a way that can be incrementally adopted without unnecessary breaking changes.
\\nToday, with the release of 13.4, you can now start adopting the App Router for production.
\\nnpm i next@latest react@latest react-dom@latest eslint-config-next@latest
We released Next.js in 2016 to provide an easy way to server-render React applications, with our goal to create a more dynamic, personalized, and global web.
\\nIn the original announcement post, we shared some design principles of Next.js:
\\nNext.js is now six years old. Our original design principles have remained—and as Next.js has been adopted by more developers and companies, we have been working on a foundational upgrade to the framework to better achieve these principles.
\\nWe\'ve been working on the next generation of Next.js, and today with 13.4
, this next generation is stable and ready for adoption. This post will share more about our design decisions and choices for the App Router.
File-system based routing has been a core feature of Next.js. In our original post, we showed this example of creating a route from a single React component:
\\n// Pages Router\\n \\nimport React from \'react\';\\nexport default () => <h1>About us</h1>;
There was nothing additional to configure. Drop a file inside pages/
and the Next.js router would take care of the rest. We still love this simplicity with routing. But as usage of the framework grew, so have the types of interfaces developers are looking to build with it.
Developers have asked for improved support for defining layouts, nesting pieces of UI as layouts, and having more flexibility over defining loading and error states. This wasn\'t an easy thing to retrofit into the existing Next.js router.
\\nEvery part of the framework has to be designed around the router. Page transitions, data fetching, caching, mutating and revalidating data, streaming, styling content, and more.
\\nTo make our router compatible with streaming, and to solve these requests for enhanced support for layouts, we set out to build a new version of our router.
\\nThis is where we landed after our initial release of our Layouts RFC.
\\n// New: App Router ✨\\nexport default function RootLayout({ children }) {\\n return (\\n <html lang=\\"en\\">\\n <body>{children}</body>\\n </html>\\n );\\n}
export default function Page() {\\n return <h1>Hello, Next.js!</h1>;\\n}
What\'s more important than what you see here is what you don\'t see. This new router (which can be incrementally adopted through the app/
directory) has an entirely different architecture, built on the foundation of React Server Components and Suspense.
This foundation has allowed us to remove Next.js specific APIs that were initially developed to extend the React primitives. For example, you no longer have to use a custom _app
file to customize the global shared layout:
// Pages Router\\n \\n// This \\"global layout\\" wraps all routes. There\'s no way to\\n// compose other layout components, and you cannot fetch global\\n// data from this file.\\nexport default function MyApp({ Component, pageProps }) {\\n return <Component {...pageProps} />;\\n}
With the Pages Router, layouts were not able to be composed, and data fetching could not be colocated with the component. With the new App Router, this is now supported.
\\n// New: App Router ✨\\n// The root layout is shared for the entire application\\nexport default function RootLayout({ children }) {\\n return (\\n <html lang=\\"en\\">\\n <body>{children}</body>\\n </html>\\n );\\n}
// Layouts can be nested and composed\\nexport default function DashboardLayout({ children }) {\\n return (\\n <section>\\n <h1>Dashboard</h1>\\n {children}\\n </section>\\n );\\n}
With the Pages Router, _document
was used to customize the initial payload from the server.
// Pages Router\\n \\n// This file allows you to customize the <html> and <body> tags\\n// for the server request, but adds framework-specific features\\n// rather than writing HTML elements.\\nimport { Html, Head, Main, NextScript } from \'next/document\';\\n \\nexport default function Document() {\\n return (\\n <Html>\\n <Head />\\n <body>\\n <Main />\\n <NextScript />\\n </body>\\n </Html>\\n );\\n}
With the App Router, you no longer need to import <Html>
, <Head>
, and <Body>
from Next.js. Instead, you just use React.
// New: App Router ✨\\n// The root layout is shared for the entire application\\nexport default function RootLayout({ children }) {\\n return (\\n <html lang=\\"en\\">\\n <body>{children}</body>\\n </html>\\n );\\n}
The opportunity to build a new file-system router was also the right time to address many other related feature requests with our routing system. For example:
\\n_app.js
. This was a less-than-ideal developer experience. With the App Router, you can import (and colocate) any CSS file in any component.getServerSideProps
) meant that interacting with your application was blocked until the entire page was hydrated. With the App Router, we\'ve refactored the architecture to be deeply integrated with React Suspense, meaning we can selectively hydrate parts of the page, without blocking other components in the UI from being interactive. Content can be instantly streamed from the server, improving the perceived loading performance of a page.The router is the core of what makes Next.js work. But it\'s not about the router itself, but how it integrates the rest of the pieces of the framework—like data fetching.
\\nNext.js and React developers want to write JavaScript and TypeScript code and compose application components together. From our original post:
\\nimport React from \'react\';\\nimport Head from \'next/head\';\\n \\nexport default () => (\\n <div>\\n <Head>\\n <meta name=\\"viewport\\" content=\\"width=device-width, initial-scale=1\\" />\\n </Head>\\n <h1>Hi. I\'m mobile-ready!</h1>\\n </div>\\n);
\\n\\nIn future versions of Next.js, we added a DX improvement to automatically import React for you.
\\n
This component encapsulates logic that can be reused and composed anywhere in your application. Paired with file-system routing, this meant an easy way to get started building React applications that felt like writing JavaScript and HTML.
\\nFor example, if you wanted to fetch some data, the original version of Next.js looked like this:
\\nimport React from \'react\';\\nimport \'isomorphic-fetch\';\\n \\nexport default class extends React.Component {\\n static async getInitialProps() {\\n const res = await fetch(\'https://api.company.com/user/123\');\\n const data = await res.json();\\n return { username: data.profile.username };\\n }\\n}
\\n\\nIn future versions of Next.js, we added a DX improvement that polyfilled fetch so you didn\'t need to import
\\nisomorphic-fetch
ornode-fetch
, and could use the Webfetch API
on both the client and server.
As adoption grew and the framework matured, we explored new patterns for data fetching.
\\ngetInitialProps
ran both the server and client. This API extended the React component, allowing you to make a Promise
and forward the results to the component\'s props
.
While getInitialProps
does still work today, we then iterated forward on the next generation of data fetching APIs based on customer feedback: getServerSideProps
and getStaticProps
.
// Generate a static version of the route\\nexport async function getStaticProps(context) {\\n return { props: {} };\\n}\\n// Or dynamically server-render the route\\nexport async function getServerSideProps(context) {\\n return { props: {} };\\n}
These APIs made it more clear where your code was running, either the client or server, and allowed Next.js applications to be automatically statically optimized. Further, it allowed for static exports, enabling Next.js to be deployed to places that don\'t support a server (e.g. AWS S3 bucket).
\\nHowever, this was not \\"just JavaScript\\", and we wanted to adhere closer to our original design principle.
\\nSince Next.js was created, we\'ve worked closely with the React core team at Meta to build framework features on top of React primitives. Our partnership, in combination with the years of research and development from the React core team, has led to an opportunity for Next.js to achieve our goals through the latest version of the React architecture, including Server Components.
\\nWith the App Router, you fetch data using the familiar async
and await
syntax. There are no new APIs to learn. By default, all components are React Server Components, so data fetching happens securely on the server. For example:
export default async function Page() {\\n const res = await fetch(\'https://api.example.com/...\');\\n // The return value is *not* serialized\\n // You can use Date, Map, Set, etc.\\n const data = res.json();\\n \\n return \'...\';\\n}
Critically, the \\"data fetching is up to the developer\\" principle is realized. You can fetch data and compose any component. And not just first-party components, but any component in the Server Components ecosystem, like a Twitter embed react-tweet
, which has been designed to integrate with Server Components and run entirely on the server.
import { Tweet } from \'react-tweet\';\\n \\nexport default async function Page() {\\n return <Tweet id=\\"790942692909916160\\" />;\\n}
Since the router is integrated with React Suspense, you can more fluidly display fallback content while parts of your content are loading, and progressively reveal content as desired.
\\nimport { Suspense } from \'react\';\\nimport { PostFeed, Weather } from \'./components\';\\n \\nexport default function Page() {\\n return (\\n <section>\\n <Suspense fallback={<p>Loading feed...</p>}>\\n <PostFeed />\\n </Suspense>\\n <Suspense fallback={<p>Loading weather...</p>}>\\n <Weather />\\n </Suspense>\\n </section>\\n );\\n}
Further, the router marks page navigations as transitions, enabling route transitions to be interruptible.
\\nWhen we created Next.js, it was still common for developers to manually configure webpack, babel, and other tooling to get a React application running. Adding further optimizations like server rendering or code splitting was often not implemented in custom solutions. Next.js, as well as other React frameworks, created an abstraction layer to implement and force these best practices.
\\nRoute-based code splitting meant that each file in your pages/
directory would be code split into its own JavaScript bundle, helping reduce the file system and improve initial page load performance.
This was beneficial for both server-rendered applications as well as single-page applications with Next.js, as the latter often loaded a single large JavaScript bundle on application startup. However, to implement component-level code splitting, developers needed to use next/dynamic
to dynamically import components.
import dynamic from \'next/dynamic\';\\n \\nconst DynamicHeader = dynamic(() => import(\'../components/header\'), {\\n loading: () => <p>Loading...</p>,\\n});\\n \\nexport default function Home() {\\n return <DynamicHeader />;\\n}
With the App Router, Server Components are not included in the JavaScript bundle for the browser. Client components are automatically code split by default (either with webpack or Turbopack in Next.js). Further, since the entire router architecture is streaming and Suspense enabled, you can progressively send parts of your UI from the server to the client.
\\nFor example, you can code split entire code paths with conditional logic. In this example, you would not need to load the dashboard\'s client-side JavaScript for logged-out users.
\\nimport { getUser } from \'./auth\';\\nimport { Dashboard, Landing } from \'./components\';\\n \\nexport default async function Layout() {\\n const isLoggedIn = await getUser();\\n return isLoggedIn ? <Dashboard /> : <Landing />;\\n}
Turbopack, our new bundler we\'re testing and stabilizing through Next.js, helps speed up local iterations while working on your Next.js application (through next dev --turbo
) and soon your production builds (next build --turbo
).
Since the alpha release in Next.js 13, we\'ve seen a steady growth in adoption as we\'ve worked to patch bugs and add support for missing features. We\'ve been dogfooding Turbopack on Vercel.com and with many Vercel customers operating large Next.js websites to gather feedback and improve stability. We are grateful for the community\'s support in testing and reporting bugs to our team.
\\nNow six months later, we\'re ready to move forward into the beta phase.
\\nTurbopack does not yet have full feature parity with webpack and Next.js. We are tracking support for those features in this issue. However, the majority of use cases should now be supported. Our goal with this beta is to continue addressing remaining bugs from increased adoption and prepare for stability in a future version.
\\nOur investment into improving the incremental engine and caching layer of Turbopack will not only speed up local development, but also production builds soon. Stay tuned for a future Next.js version where you\'ll be able to run next build --turbo
for instant builds.
Try out the Turbopack beta today in Next.js 13.4 with next dev --turbo
.
The React ecosystem has seen a lot of innovation and exploration of ideas around forms, managing form state, and caching and revalidating of data. Over time, React has become more opinionated about some of these patterns. For example, recommended \\"uncontrolled components\\" for form state.
\\nThe current ecosystem of solutions has either been reusable client-side solutions or primitives built into frameworks. Until now, there hasn\'t been a way to compose server mutations and data primitives. The React team has been working on a first-party solution for mutations.
\\nWe\'re excited to announce support for experimental Server Actions in Next.js, enabling you to mutate data on the server, calling functions directly without needing to create an in-between API layer.
\\nimport kv from \'./kv\';\\n \\nexport default function Page({ params }) {\\n async function increment() {\\n \'use server\';\\n await kv.incr(`post:id:${params.id}`);\\n }\\n \\n return (\\n <form action={increment}>\\n <button type=\\"submit\\">Like</button>\\n </form>\\n );\\n}
With Server Actions, you have powerful server-first data mutations, less client-side JavaScript, and progressively enhanced forms.
\\nimport db from \'./db\';\\nimport { redirect } from \'next/navigation\';\\n \\nasync function create(formData: FormData) {\\n \'use server\';\\n const post = await db.post.insert({\\n title: formData.get(\'title\'),\\n content: formData.get(\'content\'),\\n });\\n redirect(`/blog/${post.slug}`);\\n}\\n \\nexport default function Page() {\\n return (\\n <form action={create}>\\n <input type=\\"text\\" name=\\"title\\" />\\n <textarea name=\\"content\\" />\\n <button type=\\"submit\\">Submit</button>\\n </form>\\n );\\n}
Server Actions in Next.js have been designed for deep integration with the rest of the data lifecycle, including the Next.js Cache, Incremental Static Regeneration (ISR), and the client router.
\\nRevalidating data through new APIs revalidatePath
and revalidateTag
mean that mutating, re-rendering the page, or redirecting can happen in one network roundtrip, ensuring the correct data is displayed on the client, even if the upstream provider is slow.
import db from \'./db\';\\nimport { revalidateTag } from \'next/cache\';\\n \\nasync function update(formData: FormData) {\\n \'use server\';\\n await db.post.update({\\n title: formData.get(\'title\'),\\n });\\n revalidateTag(\'posts\');\\n}\\n \\nexport default async function Page() {\\n const res = await fetch(\'https://...\', { next: { tags: [\'posts\'] } });\\n const data = await res.json();\\n // ...\\n}
Server Actions are designed to be composable. Anyone in the React community can build and publish Server Actions and distribute them in the ecosystem. Just like Server Components, we\'re excited about the new era of composable primitives for both the client and the server.
\\nServer Actions are available today in alpha with Next.js 13.4. By opting into using Server Actions, Next.js will use the experimental release channel of React.
\\n/** @type {import(\'next\').NextConfig} */\\nconst nextConfig = {\\n experimental: {\\n serverActions: true,\\n },\\n};\\n \\nmodule.exports = nextConfig;
pages
and app
. We\'ve enhanced and simplified the existing Preview Mode API, which continues to work for pages
. Preview Mode does not work in app
—you should use Draft Mode.Marking the App Router as stable today does not mean our work is done. Stability means that the core of the App Router is ready for production and has been validated by both our own internal testing, as well as many Next.js early adopters.
\\nThere are still additional optimizations we\'d like to make in the future, including Server Actions reaching full stability. It was important for us to push towards core stability to help provide clarity for the community on where they should begin learning and building applications today.
\\nThe App Router is built on top of the React canary
channel, which is now ready for framework adoption of features like Server Components. Learn more.
Starting today, we recommend building new applications with the App Router. The Next.js beta documentation, which has been used to explain the App Router and re-written from the ground up, is now merged back into the stable Next.js documentation. You can now easily toggle between the App or Pages Router.
\\nWe recommend reading the App Router Incremental Adoption Guide to learn how to adopt the App Router.
\\nNo. We are committed to supporting pages/
development, including bug fixes, improvements, and security patches, for multiple major versions moving forward. We want to ensure developers have enough time to incrementally adopt the App Router as they\'re ready.
Using both pages/
and app/
in production together is supported and encouraged. The App Router can be adopted on a per-route basis.
Next.js is one framework that is choosing the build on the React architecture, which includes Server Components. We hope that the experience provided with the App Router will encourage other frameworks (or new frameworks) to consider using this architecture, as well.
\\nThere are still patterns yet to be defined in this ecosystem, like handling infinite scroll. For now, we recommend using client solutions for these patterns while the ecosystem grows and libraries are created or updated.
\\nNext.js is the result of the combined work of over 2,600 individual developers, industry partners like Google and Meta, and our core team at Vercel. Join the community on GitHub Discussions, Reddit, and Discord.
\\nThis release was brought to you by:
\\nAnd the contributions of: @shuding, @huozhi, @wyattfry, @styfle, @sreetamdas, @afonsojramos, @timneutkens, @alexkirsz, @chriswdmr, @jankaifer, @pn-code, @kdy1, @sokra, @kwonoj, @martin-wahlberg, @Kikobeats, @JTaylor0196, @sebmarkbage, @ijjk, @gnoff, @jridgewell, @sagarpreet-xflowpay, @balazsorban44, @cprussin, @ForsakenHarmony, @li-jia-nan, @dciug, @albertothedev, @DuCanhGH, @feedthejim, @patrick91, @padmaia, @sophiebits, @eps1lon, @reconbot, @acdlite, @cjmling, @nabsul, @motopods, @hanneslund, @tunamagur0, @devknoll, @apeltop, @maranomynet, @y-tsubuku, @EndangeredMassa, @ykzts, @AviAvinav, @adilansari, @wyattjoh, @charkour, @delbaoliveira, @agadzik, @Just-Moh-it, @rodrigofeijao, @leerob, @juliusmarminge, @koba04, @Phiction, @jessewarren-aa, @ryo-manba, @Yovach, and @dylanjha.
","description":"Next.js 13.4 is a foundational release, marking stability for the App Router: App Router (Stable):\\nReact Server Components\\nNested Routes & Layouts\\nSimplified Data Fetching\\nStreaming & Suspense\\nBuilt-in SEO Support\\nTurbopack (Beta): Your local dev server, faster and with…","guid":"https://nextjs.org/blog/next-13-4","author":null,"authorUrl":null,"authorAvatar":null,"publishedAt":"2023-05-03T16:00:00.975Z","media":null,"categories":null,"attachments":null,"extra":null,"language":null},{"title":"Next.js 13.3","url":"https://nextjs.org/blog/next-13-3","content":"Next.js 13.3 adds popular community-requested features, including:
\\nUpdate today by running:
\\nnpm i next@latest react@latest react-dom@latest eslint-config-next@latest
We are closing in on marking App Router as stable in the next minor release and are shifting our focus to optimizing performance, enhancing behaviors, and fixing bugs.
\\nWhile we\'re still working on a few features like Mutations we don\'t expect these to impact the API surface of other App Router features. We\'re excited to see what you build with the App Router and look forward to your feedback.
\\nIn Next.js 13.2, we announced a new Metadata API, allowing you to define metadata (e.g. title
, meta
, and link
tags inside your HTML head
element) by exporting a Metadata object from a layout or page.
// either Static metadata\\nexport const metadata = {\\n title: \'Home\',\\n};\\n// Output:\\n// <head>\\n// <title>Home</title>\\n// </head>\\n \\n// or Dynamic metadata\\nexport async function generateMetadata({ params, searchParams }) {\\n const product = await getProduct(params.id);\\n return { title: product.title };\\n}\\n// Output:\\n// <head>\\n// <title>My Unique Product</title>\\n// </head>\\n \\nexport default function Page() {}
In addition to config-based metadata, the Metadata API now supports new file conventions, allowing you to conveniently customize your pages for improved SEO and sharing on the web:
\\nopengraph-image.(jpg|png|svg)
twitter-image.(jpg|png|svg)
favicon.ico
icon.(ico|jpg|png|svg)
sitemap.(xml|js|jsx|ts|tsx)
robots.(txt|js|jsx|ts|tsx)
manifest.(json|js|jsx|ts|tsx)
For example, you can use file-based metadata to add a favicon for your app and an open graph image for your /about
page:
app\\n├── favicon.ico\\n├── layout.js\\n├── page.js\\n└── about\\n ├── opengraph-image.jpg\\n └── page.js
Next.js will automatically serve these files with hashes (for the file name) in production for caching, and update the relevant head
elements with the correct metadata information such as the asset\'s URL, file type, and image size.
// Visiting \\"/\\"\\n<link rel=\\"icon\\" href=\\"<computedUrl>\\"/>\\n \\n// Visiting \\"/about\\"\\n<link rel=\\"icon\\" href=\\"<computedUrl>\\"/>\\n<meta property=\\"og:image\\" content=\\"<computedUrl>\\" type=\\"<computedType>\\" ... />
Adding static files to your application is often the simplest approach, but there are cases where you may need to create files dynamically. For each static file convention, there\'s an accompanying dynamic (.js|.jsx|.ts|.tsx)
variant that allows you to write code to generate the file.
For example, while you can add a static sitemap.xml
file, most sites have some pages that are dynamically generated using an external data source. To generate a dynamic sitemap, you can add a sitemap.js
file that returns an array of your dynamic routes.
export default async function sitemap() {\\n const res = await fetch(\'https://.../posts\');\\n const allPosts = await res.json();\\n \\n const posts = allPosts.map((post) => ({\\n url: `https://acme.com/blog/${post.slug}`,\\n lastModified: post.publishedAt,\\n }));\\n \\n const routes = [\'\', \'/about\', \'/blog\'].map((route) => ({\\n url: `https://acme.com${route}`,\\n lastModified: new Date().toISOString(),\\n }));\\n \\n return [...routes, ...posts];\\n}
With config-based and new file-based options, you now have a comprehensive Metadata API to cover both static and dynamic metadata.
\\nThe Metadata API is available in 13.3 for the App Router (app
). It is not available in the pages
directory. Learn more about file-based metadata and view the API reference.
Six months ago, we released @vercel/og and Satori, libraries that allow you to generate images dynamically using JSX, HTML, and CSS.
\\n@vercel/og
was put to the test at Next.js Conf, generating over 100,000 dynamic ticket images for every attendee. With extensive adoption across Vercel customers and over 900,000 downloads since the release, we\'re excited to bring dynamically generated images to all Next.js applications without the need for an external package.
You can now import ImageResponse
from next/server
to generate images:
import { ImageResponse } from \'next/server\';\\n \\nexport const size = { width: 1200, height: 600 };\\nexport const alt = \'About Acme\';\\nexport const contentType = \'image/png\';\\nexport const runtime = \'edge\';\\n \\nexport default function og() {\\n return new ImageResponse();\\n // ...\\n}
ImageResponse
naturally integrates well with other Next.js APIs, including Route Handlers and file-based Metadata. For example, you can use ImageResponse
in a opengraph-image.tsx
file to generate Open Graph and Twitter images at build time or dynamically at request time.
Learn more about the Image Response API.
\\nThe Next.js App Router now supports fully static exports.
\\nYou can start as a static site or Single-Page Application (SPA), then later optionally upgrade to use Next.js features that require a server.
\\nWhen running next build
, Next.js generates an HTML file per route. By breaking a strict SPA into individual HTML files, Next.js can avoid loading unnecessary JavaScript code on the client-side, reducing the bundle size and enabling faster page loads.
/**\\n * @type {import(\'next\').NextConfig}\\n */\\nconst nextConfig = {\\n output: \'export\',\\n};\\n \\nmodule.exports = nextConfig;
Static Export works with the app
router\'s new features including static Route Handlers, Open Graph images, and React Server Components.
For example, Server Components will run during the build, similar to traditional static-site generation, rendering the components into static HTML for the initial page load and a static payload for client navigation between routes.
\\nPreviously, to use Static Export in the pages
directory, you needed to run next export
. However, with the next.config.js
option, next build
will output a out
directory when output: \'export\'
is set. You can use the same configuration for the app
router and pages
directory. This means next export
is no longer required.
With advanced static export support, you\'ll get errors earlier in the development process (next dev
), such as when attempting to use a dynamic function that requires a server like cookies()
or headers()
.
Learn more about Static Export.
\\nNext.js 13.3 introduces new dynamic conventions that allow you to implement advanced routing cases: Parallel Routes and Intercepting Routes. These features enable you to show more than one page in the same view, like with complex dashboards or modals.
\\nWith Parallel Routes, you can simultaneously render one or more pages in the same view that can be navigated independently. It can also be used to conditionally render pages.
\\nParallel Routes are created using named \\"slots\\". Slots are defined with the @folder
convention:
dashboard\\n├── @user\\n│ └── page.js\\n├── @team\\n│ └── page.js\\n├── layout.js\\n└── page.js
The layout in the same route segment accepts the slots as props:
\\nexport default async function Layout({ children, user, team }) {\\n const userType = getCurrentUserType();\\n \\n return (\\n <>\\n {userType === \'user\' ? user : team}\\n {children}\\n </>\\n );\\n}
In the example above, the @user
and @team
parallel route slots (explicit) are conditionally rendered based on your logic. children
is an implicit route slot that does not need to be mapped to a @folder
. For example, dashboard/page.js
is equivalent to dashboard/@children/page.js
.
Intercepting routes allow you to load a new route within the current layout while \\"masking\\" the browser URL. This is useful when keeping the context of the current page is important, such as expanding a photo in a feed through a modal where the feed is kept in the background of the modal.
\\nIntercepting routes can be defined with the (..)
convention, similar to relative paths ../
. You can also use the (...)
convention to create a path relative to the app
directory.
feed\\n├── @modal\\n│ └── (..)photo\\n│ └── [id]\\n│ └── page.tsx\\n├── page.tsx\\n└── layout.tsx\\nphoto\\n└── [id]\\n └── page.tsx
In the example above, clicking the photo from the user\'s profile will open the photo in a modal during client-side navigation. However, refreshing or sharing the page will load the photo with its default layout.
\\nThis solves the challenges you may have when creating modals, such as making the modal content shareable through an URL, preventing context from being lost when the page is refreshed, and closing and reopening the modal with backward and forward navigation.
\\nFor more examples and behavior, see the Parallel and Intercepting Routes documentation.
\\nnext/font
options, and streaming with Server Components as it approaches beta (see demo). We\'ve also patched additional bugs discovered while dogfooding on mature Next.js apps like vercel.com and nextjs.org. Learn more.next.config.js
: Making changes to next.config.js
will now automatically restart your local dev server. This extends automatic reloading of .env
, .env.*
, jsconfig.json
, tsconfig.json
configuration files.pages
. This feature announces client-side route transitions to screen readers and other assistive technology. Learn more.redirects
and rewrites
set in next.config.js
are now considered during type checking. Learn more.create-next-app
: When starting a new project with npx create-next-app@latest
, you can now optionally select Tailwind CSS, or use the --tailwind
flag, to preconfigure your application with this styling solution.export default
instead of a supported HTTP verb now throws a helpful error with route.ts
. Learn more about Route Handlers.next/image
now supports the fetchPriority=\\"high\\"
attribute.head.js
), which was deprecated in 13.2, has been removed. Instead, use the built-in support for SEO through the Metadata API.app/_dashboard/page.tsx
would not be routable.useParams
client component hook to read the dynamic parameters for the given route segment. Learn more.notFound()
errors, the root app/not-found.js
file will also handle any unmatched URLs for your whole application. This means users that visit a URL that is not handled by your app will be shown the UI exported by the app/not-found.js
file. Learn more.router.refresh()
will now invalidate the entire cache and search params are now part of the cache key allowing navigation between two search params (e.g. /?search=leerob
and /?search=tim
) to correctly restore content that relied on the param.Next.js is the result of the combined work of over 2,600 individual developers, industry partners like Google and Meta, and our core team at Vercel. With over 4.2 million npm downloads per week and 104,000+ GitHub stars, Next.js is one of the most popular ways of building the Web.
\\nJoin the community on GitHub Discussions, Reddit, and Discord.
\\nThis release was brought to you by:
\\nAnd the contributions of: @shuding, @huozhi, @sokra, @hanneslund, @JesseKoldewijn, @kaguya3222, @yangshun, @ijjk, @konomae, @Brooooooklyn, @jridgewell, @zlrlyy, @JohnDaly, @abhiyandhakal, @benjie, @johnnyomair, @nk980113, @dirheimerb, @DerTimonius, @DuCanhGH, @padmaia, @stafyniaksacha, @Gladowar, @zek, @jankaifer, @styfle, @balazsorban44, @wbinnssmith, @chibicode, @ForsakenHarmony, @franktronics, @FSaldanha, @Schniz, @raisedadead, @AdamKatzDev, @wyattjoh, @leerob, @meesvandongen, @vladikoff, @feedthejim, @tka5, @pyjun01, @gdborton, @M3kH, @aretrace, @shivanshubisht, @alexkirsz, @agrattan0820, @vinaykulk621, @heyitsuzair, @mrkldshv, @timneutkens, @furkanmavili, @swaminator, @EndangeredMassa, @DevEsteves, @rishabhpoddar, @schehata, @molebox, @dlehmhus, @akshaynox, @sp00ls, @janicklas-ralph, @tomryanx, @kwonoj, @karlhorky, @kdy1, @dante-robinson, @lachlanjc, @ianmacartney, @hotters, @isaackatayev, @insik-han, @jayair, @ivanhofer, @javivelasco, @SukkaW, @visshaljagtap, @imranbarbhuiya, @nivak-monarch, @HarshaVardhanReddyDuvvuru, @ianldgs, @ricardofiorani, @swarnava, and @gustavostz.
","description":"Next.js 13.3 adds popular community-requested features, including: File-Based Metadata API: Dynamically generate sitemaps, robots, favicons, and more.\\nDynamic Open Graph Images: Generate OG images using JSX, HTML, and CSS.\\nStatic Export for App Router: Static / Single-Page…","guid":"https://nextjs.org/blog/next-13-3","author":null,"authorUrl":null,"authorAvatar":null,"publishedAt":"2023-04-05T16:00:00.533Z","media":[{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Fnext-13-3%2Fmodal-routing.png&w=3840&q=75","type":"photo","width":1198.6666666666667,"height":1353},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Fnext-13-3%2Fmodal-routing.png&w=3840&q=75","type":"photo","width":1198.6666666666667,"height":1353}],"categories":null,"attachments":null,"extra":null,"language":null},{"title":"Next.js 13.2","url":"https://nextjs.org/blog/next-13-2","content":"Next.js 13.2 includes major improvements to the App Router (app
) in preparation for stability:
meta
tags.Request
and Response
.next/link
and TypeScript.Update today by running:
\\nnpm i next@latest react@latest react-dom@latest eslint-config-next@latest
Next.js has been designed from the beginning to enable optimization for search engines.
\\nServing pre-rendered HTML content not only helps improve indexing for search engines but also improves the performance of your application. While Next.js has provided a simple API for modifying metadata in your application (next/head
) for many versions, we wanted to redesign and enhance how you optimize for search engines with the App Router (app
).
The new Metadata API allows you to define metadata (e.g. meta
and link
tags inside your HTML head
element) with an explicit metadata configuration in any layout or page that is a Server Component.
import type { Metadata } from \'next\';\\n \\nexport const metadata: Metadata = {\\n title: \'Home\',\\n description: \'Welcome to Next.js\',\\n};
This API is simple, composable, and designed to be compatible with streaming server rendering. For example, you can set common metadata attributes in your root layout for the entire application, and compose and merge metadata objects together for other routes in your application.
\\nThis includes support for dynamic metadata as well as static:
\\n// Static metadata\\nexport const metadata = {\\n title: \'...\',\\n};\\n \\n// Dynamic metadata\\nexport async function generateMetadata({ params, searchParams }) {\\n const product = await getProduct(params.id);\\n return { title: product.title };\\n}
All metadata options are available, including the ability to provide custom metadata, with support for TypeScript through the TypeScript plugin or by adding the Metadata
type.
For example, you can define open graph images through metadata:
\\nexport const metadata = {\\n openGraph: {\\n title: \'Next.js\',\\n description: \'The React Framework for the Web\',\\n url: \'https://nextjs.org\',\\n siteName: \'Next.js\',\\n images: [\\n {\\n url: \'https://nextjs.org/og.png\',\\n width: 800,\\n height: 600,\\n },\\n ],\\n locale: \'en-US\',\\n type: \'website\',\\n },\\n};\\n \\nexport default function Layout({ children }) {}
The Metadata API is available in 13.2 for the App Router (app
), replacing the previous head.js
special file. It is not available for the pages
directory.
Learn more about SEO or view the API reference for Metadata. We\'d like to thank next-seo for their work on the community package and feedback on the initial API design.
\\nOne of the missing pieces for the original beta release of the App Router (app
) was API Routes, which exist in the pages/api
directory. We wanted to take this opportunity to create a new, more modern version of API Routes that were deeply integrated into the new routing system for app
.
Route Handlers allow you to create custom request handlers for a given route using the Web Request and Response APIs.
\\nexport async function GET(request: Request) {}
Route Handlers have an isomorphic API to support both Edge and Node.js runtimes seamlessly, including support for streaming responses. Since Route Handlers use the same route segment configuration as pages and layouts, they support long-awaited features like general-purpose Static Rendering and Revalidation.
\\nA route.ts
file can export an async function named by the HTTP verbs: GET
, HEAD
, OPTIONS
, POST
, PUT
, DELETE
, and PATCH
. These functions can then be wrapped and abstracted to create helpers / reusable logic for your custom route logic.
Other server functions, like cookies
and headers
, can be used inside Route Handlers – along with any Web APIs these abstractions are built upon. This allows for code to be shared between Server Components and Route Handlers.
import { cookies } from \'next/headers\';\\n \\nexport async function GET(request: Request) {\\n const cookieStore = cookies();\\n const token = cookieStore.get(\'token\');\\n \\n return new Response(\'Hello, Next.js!\', {\\n status: 200,\\n headers: { \'Set-Cookie\': `token=${token}` },\\n });\\n}
Route Handlers are available in 13.2 for the App Router (app
) using the route.ts
special file. They are not available in the pages
directory, as they are a replacement for API Routes.
Learn more about Route Handlers or view the API reference. We\'d like to thank SvelteKit for their prior art and inspiration here.
\\nMDX is a superset of markdown that lets you write JSX directly in your markdown files. It is a powerful way to add dynamic interactivity and embed React components within your content.
\\nWith 13.2, you can now use MDX entirely with React Server Components – meaning less client-side JavaScript for faster page loads, all while retaining the powerful capabilities of React for templating dynamic UI. You can sprinkle interactivity into your MDX content as needed.
\\nThe @next/mdx
plugin has been updated with support for a new special file, mdx-components.js|ts
, defined at the root of your application to provide custom components:
// This file allows you to provide custom React components\\n// to be used in MDX files. You can import and use any\\n// React component you want, including components from\\n// other libraries.\\nfunction H1({ children }) {\\n // ...\\n}\\n \\nfunction H2({ children }) {\\n // ...\\n}\\n \\nexport function useMDXComponents(components) {\\n return { h1: H1, h2: H2, ...components };\\n}
Further, we\'ve worked with community packages for fetching MDX content next-mdx-remote
and contentlayer
to add support for React Server Components.
Learn more about how to setup MDX with Server Components or deploy our example.
\\nAs part of enabling MDX for Server Components, we\'ve also rewritten the MDX parser in Rust to improve performance. This is a significant improvement over the previous JavaScript-based parser, which saw noticable slowdowns when processing a large number of MDX files.
\\nYou can opt-into using the Rust parser in next.config.js
. For example, with @next/mdx
:
/** @type {import(\'next\').NextConfig} */\\nconst nextConfig = {\\n experimental: {\\n appDir: true,\\n mdxRs: true,\\n },\\n};\\n \\nconst withMDX = require(\'@next/mdx\')();\\nmodule.exports = withMDX(nextConfig);
We\'d like to thank Titus Wormer who we sponsored to work on this project. If you\'d like to use this outside of Next.js, check out the new package mdxjs-rs.
\\nNext.js can now statically type links in the app
directory to prevent typos and other errors when using next/link
, improving type safety when navigating between pages.
import Link from \'next/link\'\\n \\n// ✅\\n<Link href=\\"/about\\" />\\n// ✅\\n<Link href=\\"/blog/nextjs\\" />\\n// ✅\\n<Link href={`/blog/${slug}`} />\\n \\n// ❌ TypeScript errors if href is not a valid route\\n<Link href=\\"/aboot\\" />
This feature requires using the new App Router, as well as TypeScript.
\\n/** @type {import(\'next\').NextConfig} */\\nconst nextConfig = {\\n experimental: {\\n appDir: true,\\n typedRoutes: true,\\n },\\n};\\n \\nmodule.exports = nextConfig;
This feature is now available in beta. rewrites
and redirects
are not yet supported.
Learn more about statically typed routes.
\\nTo help improve the readability and debugability of errors, we\'ve made a number of improvements to the Next.js error overlay.
\\nIn 13.2, Next.js and React stack traces are now separated, making it easier to identify where the error is coming from. Additionally, the error overlay now displays the current version of Next.js, helping you understand whether your version is up to date.
\\nWe\'ve also improved the error output for React hydration errors, which are now more readable and easier to debug.
\\nTurbopack, announced in alpha with Next.js 13, is an incremental bundler designed to speed up both local development, as well as production builds in the future.
\\nWe\'ve been focused on supporting existing Next.js features in Turbopack and improving overall stability as we move towards beta. Since our last release, we\'ve added:
\\nnext/dynamic
rewrites
, redirects
, headers
, and pageExtensions
in next.config.js
pages
composes: ... from ...
We\'ve also fixed many bugs and improved stability while dogfooding Turbopack with some of our largest internal Next.js applications and with early Vercel customers.
\\nTurbopack now ships with support and compatibility for some webpack loaders. This means that you can use many loaders from the Webpack ecosystem to transform files of different types to JavaScript. Loaders like @mdx-js/loader
, @svgr/webpack
, and babel-loader
are supported. Learn more about customizing Turbopack.
For example, use experimental.turbo.loaders
to configure a list of loaders for each file extension:
module.exports = {\\n experimental: {\\n turbo: {\\n loaders: {\\n \'.md\': [\\n {\\n // Option format\\n loader: \'@mdx-js/loader\',\\n options: {\\n format: \'md\',\\n },\\n },\\n ],\\n \'.svg\': [\'@svgr/webpack\'],\\n },\\n },\\n },\\n};
Check out the Turbopack example using loaders for a complete example.
\\nTurbopack can now be configured to modify module resolution through aliases, similar to webpack\'s resolve.alias
. Configure this through experimental.turbo.resolveAlias
:
module.exports = {\\n experimental: {\\n turbo: {\\n resolveAlias: {\\n underscore: \'lodash\',\\n mocha: { browser: \'mocha/browser-entry.js\' },\\n },\\n },\\n },\\n};
Next.js 13.2 introduces the new Next.js Cache (beta), an evolution of ISR that unlocks:
\\nFor pages that are entirely static, ISR works the same way as today. For pages that have more granular data fetching, mixing static and dynamic, the Next.js Cache uses a more granular, ephemeral cache.
\\nWith the foundation of React Server Components and colocated data fetching in the Next.js App Router (app
), you can now encapsulate static or dynamic data alongside their consuming component.
export default async function Page() {\\n const [staticData, dynamicData, revalidatedData] = await Promise.all([\\n // Cached until manually invalidated\\n fetch(`https://...`),\\n // Refetched on every request\\n fetch(`https://...`, { cache: \'no-store\' }),\\n // Cached with a lifetime of 10 seconds\\n fetch(`https://...`, { next: { revalidate: 10 } }),\\n ]);\\n \\n return <div>...</div>;\\n}
While developing locally with the App Router, you\'ll now see the same caching behavior in next dev
as production with next start
. This improves the speed of Fast Refresh when any Server Component or data loading code changes.
With the Next.js Cache, your app controls the cache—not third-party APIs. This differs from cache-control
headers, where the upstream controls how long the value is cached.
Next.js on Vercel gives you framework-defined infrastructure. You write application code, like component-level data fetching with fetch
, and we scaffold globally distributed infrastructure for you with no additional effort.
The new Next.js Cache makes changing code independent from changing data. This can drastically speed up the redeployment of static pages, since the generation of these pages can use the existing cache.
\\nThis new Vercel Cache API is designed to work with any framework, but has native integration with the Next.js Cache. Learn more about how ISR evolved into the Next.js Cache, as well as how the Next.js Cache works when deploy to Vercel.
\\nWhen self-hosting, an LRU cache is used, which defaults to 50 MB. All entries into the cache are automatically written to disk by default. This filesystem cache can be shared between nodes if they have the same cache key, similar to how ISR works today.
\\nFor developers looking to further customize and modify the core of the Next.js Cache, they can modify underlying cache keys and change how and where cache entries are persisted, including disabling persistence entirely.
\\n@next/font
is now built-in to Next.js as next/font
. This means you no longer need to install @next/font
separately. Learn more.font-display
property for next/font
has been changed to font-display: swap
instead of optional
based on community feedback.images.contentDispositionType: \\"attachment\\"
to force download images when visiting the Image Optimization API directly (PR).Next.js is the result of the combined work of over 2,500 individual developers, industry partners like Google and Meta, and our core team at Vercel. With over 3.9 million npm downloads per week and 100,000+ GitHub stars, Next.js is one of the most popular ways of building the Web.
\\nJoin the community on GitHub Discussions, Reddit, and Discord.
\\nThis release was brought to you by:
\\nAnd the contributions of: @timneutkens, @loettz, @okcoker, @clive-h-townsend, @shuding, @JanKaifer, @sepiropht, @hanneslund, @huozhi, @aralroca, @balazsorban44, @cristobaldominguez95, @vinaykulk621, @Brooooooklyn, @feedthejim, @samsisle, @MarDi66, @styfle, @therealrinku, @sebmarkbage, @cravend, @hu0p, @kdy1, @ijjk, @juzhiyuan, @IvanKiral, @LukeSchlangen, @wojtekolek, @samdenty, @Josehower, @bennettdams, @SCG82, @mike-plummer, @kwonoj, @David0z, @denchance, @joulev, @wbinnssmith, @alexkirsz, @UnknownMonk, @leerob, @sairajchouhan, @imranbarbhuiya, @jomeswang, @ductnn, @thomasballinger, @chibicode, @jridgewell, @sreetamdas, @Juneezee, @SukkaW, @wyattjoh, @michaeloliverx, @cattmote, @joefreeman, @valentincostam, @qrohlf, @ossan-engineer, @rishabhpoddar, @vasucp1207, @Schniz, @andrii-bodnar, @gergelyke, @abstractvector, @wherehows, @BrodaNoel, @taep96, @abe1272001, @0xadada, @nbouvrette, @teobler, @lubakravche, @molebox, and @hiddenest.
","description":"Next.js 13.2 includes major improvements to the App Router (app) in preparation for stability: Built-in SEO Support: New Metadata API to set static and dynamic meta tags.\\nRoute Handlers: Custom request handlers, built on Web Request and Response.\\nMDX for Server Components: Use…","guid":"https://nextjs.org/blog/next-13-2","author":null,"authorUrl":null,"authorAvatar":null,"publishedAt":"2023-02-22T16:00:00.541Z","media":[{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Fnext-13-2%2Ferror.png&w=1920&q=75","type":"photo","width":954,"height":553},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Fnext-13-2%2Ferror.png&w=1920&q=75","type":"photo","width":954,"height":553}],"categories":null,"attachments":null,"extra":null,"language":null},{"title":"Next.js 13.1","url":"https://nextjs.org/blog/next-13-1","content":"Next.js 13.1 includes improvements to both the pages/
(stable) and app/
(beta) directories:
app
Directory (Beta) Improvements: Improved reliability and performance.next-transpile-modules
capabilities into core.next/image
, @next/font
, and more.Update today by running:
\\nnpm i next@latest react@latest react-dom@latest eslint-config-next@latest
app
directoryIn Next.js 13, we announced the new app
directory (beta). This new routing and data fetching system can be incrementally adopted alongside your existing pages
directory.
The app
directory provides many benefits, including enhanced layouts, co-location of components, tests, and styles, component-level data fetching, and more. Thanks to your feedback and early testing, we\'ve made several improvements to the reliability of the app
directory:
app
directory added additional <div>
elements to scroll layouts into view when navigating. With 13.1, these extra elements are no longer created. The scrolling behavior is preserved.useState
in Server Components). Learn more.cache()
and fetch()
for layouts and pages, memory leaks, and more.app
directory now includes 9.3kB
less client-side JavaScript than the pages
directory. This baseline doesn\'t increase whether you add 1 or 1000 Server Components to your application. The React runtime is temporarily slightly larger, the increase is caused by the React Server Components runtime, which handles mechanics that Next.js previously handled. We are working to reduce this further.pages/ | app/ | delta | |
---|---|---|---|
Total First Load JS | Baseline | -9.3kB | 12.1% smaller |
Next.js Runtime | Baseline | -12kB | 56.8% smaller |
React Runtime | Baseline | +2.7kB | 5.2% larger |
We\'re excited about continuing to make progress on the stability of the app
directory. The beta documentation for the app
directory has had hundreds of updates based on your feedback.
You can now mark dependencies from local packages (like monorepos) or from external dependencies (node_modules
) to be transpiled and bundled. This built-in support replaces the popular next-transpile-modules
package.
/** @type {import(\'next\').NextConfig} */\\nconst nextConfig = {\\n transpilePackages: [\'@acme/ui\', \'lodash-es\'],\\n};\\n \\nmodule.exports = nextConfig;
We are thankful to Pierre de la Martinière\\n(@martpie) for their work on this package and their assistance in helping ensure the built-in support met the community\'s needs.
\\nMany popular npm packages make use of \\"barrel files\\" to provide a single file that re-exports other modules. For example:
\\nexport { default as Button } from \'./dist/Button\';\\nexport { default as Slider } from \'./dist/Slider\';\\nexport { default as Dropdown } from \'./dist/Dropdown\';
This allows consumers of the package to use named exports in a single line:
\\nimport { Button, Slider, Dropdown } from \'@acme/ui\';
While bundlers understand these barrel files and can remove unused re-exports (called \\"dead code elimination\\"), this process involves parsing/compiling all re-exported files. In case of published libraries some npm packages ship barrel files that have thousands of modules re-exported, which slows down compile times. These libraries recommended babel-plugin-transform-imports
to avoid this issue, but for those using SWC, there was no previous support. We\'ve added a new SWC transform built into Next.js called modularizeImports
.
This new setting enables the SWC transform which changes your import statements based on a defined pattern. For example, the above code for using three components would be automatically converted to use direct imports, without the developer needing to write this code manually:
\\n// Before (with barrel file)\\nimport { Button, Slider, Dropdown } from \'@acme/ui\';\\n \\n// After (with modularized imports from plugin)\\nimport Button from \'@acme/ui/dist/Button\';\\nimport Slider from \'@acme/ui/dist/Slider\';\\nimport Dropdown from \'@acme/ui/dist/Dropdown\';
This transformation is possible with the modularizeImports
option in next.config.js
:
module.exports = {\\n modularizeImports: {\\n \'@acme/ui\': {\\n transform: \'@acme/ui/dist/{{member}}\',\\n },\\n },\\n};
Leveraging this transform with @mui/icons-material
or lodash
allows skipping compilation of unused files. Learn more.
View a demo to see this in action.
\\nThe Edge Runtime inside Next.js uses a strict subset of Node.js APIs (like Request
, Response
, and more) which are compatible with Edge computing platforms like Vercel or when self-hosting. These APIs run everywhere, including in the browser, allowing developers to learn them once and write everywhere.
// \\"experimental-\\" prefix is no longer needed\\nexport const config = {\\n runtime: \'edge\',\\n};\\n \\nexport default function handler(req: Request) {\\n return new Response(\'Hello World\');\\n}
Next.js Middleware already uses this light edge runtime by default for better performance. As Middleware can run before every request in your application, having a lightweight runtime is critical to ensure low latency. In Next.js 12.2, we added the ability to optionally use this runtime for API Routes as well.
\\nWith 13.1, the Edge Runtime inside Next.js is now stable for API routes. When self-hosted, Middleware and API Routes using the Edge Runtime will run as a single-region workload by default as part of next start
. On Vercel, Next.js Middleware and API Routes are deployed globally using Vercel Edge Functions for the lowest possible latency. Vercel Edge Functions are also now generally available.
After releasing the Turbopack alpha with Next.js 13, we\'ve been focused on improving reliability, adding support for the most requested features, and defining plans for plugins and usage in other frameworks.
\\nSince Next.js 13.0.0, Turbopack:
\\nnext/image
@next/font
(Google Fonts)import()
statements@ahabhgk
for their contribution)next dev
error overlayWe are thankful to Evan You and the Vite community for their feedback and contributions to ensure the Turbopack benchmarks are as accurate as possible. We\'ve worked together with the Vite team to validate the latest Turbopack benchmarks and make numerous improvements to our testing methodology.
\\nAs a result of this collaboration, we now use a more accurate metric which includes time spent in React\'s update mechanism. We were able to improve React Fast Refresh time by 30ms in Turbopack as well as Next.js 13.1 on webpack. We\'ve also added a new benchmark for using Vite with SWC, which shows improved performance compared to using the default Vite with Babel. View the updated benchmarks or read about the testing methodology.
\\nTry out the Turbopack alpha version today in Next.js 13 with next dev --turbo
. If you have any feedback let us know on the GitHub Discussion.
Thanks to your feedback, we\'re making Next.js Middleware more powerful than ever. With 13.1, you can now return responses from Middleware, as well as set headers on the request.
\\nThese API improvements give you powerful new flexibility to customize every part of the Next.js routing lifecycle. The experimental.allowMiddlewareResponseBody
configuration option inside next.config.js
is no longer required.
You can now more easily set headers on the request, as well as respond directly without having to rewrite
or redirect
:
import { NextResponse } from \'next/server\';\\n \\nexport function middleware(request: Request) {\\n // Check if a user has access...\\n if (!isAuthorized(request)) {\\n return NextResponse.json({ message: \'Unauthorized\' });\\n }\\n \\n // Add a new header, this will change the incoming request headers\\n // that you can read in getServerSideProps and API routes\\n const requestHeaders = new Headers(request.headers);\\n requestHeaders.set(\'x-version\', \'13.1\');\\n \\n return NextResponse.next({\\n request: {\\n // Apply new request headers\\n headers: requestHeaders,\\n },\\n });\\n}
Learn more about Next.js advanced Middleware.
\\n@next/font
now supports adding multiple font weights and styles in the same font declaration. Learn more.next/dynamic
now uses React primitives lazy()
and <Suspense>
. The previous suspense
option is no longer required. With these changes, next/dynamic
is now compatible with the app
directory.create-next-app
has been updated with a new design, now including @next/font
by default for automatic self-hosting of fonts with zero layout shift. Try it out with npx create-next-app@latest
or deploy the template.app
directory (beta) in Next.js 13. Deploy your own.Next.js is the result of the combined work of over 2,400 individual developers, industry partners like Google and Meta, and our core team at Vercel. With over 3.6 million npm downloads per week and 97,900+ GitHub stars, Next.js is one of the most popular ways of building the Web.
\\nJoin the community on GitHub Discussions, Reddit, and Discord.
\\nThis release was brought to you by:
\\nAnd the contributions of: @aarnadlr, @aaronbrown-vercel, @aaronjy, @abayomi185, @ademilter, @adictonator, @adilansari, @adtc, @alantoa, @aleksa-codes, @alfred-mountfield, @alpha-xek, @andarist, @andykenward, @anujssstw, @artdevgame, @artechventure, @arturbien, @aziyatali, @bennettdams, @bertho-zero, @blue-devil1134, @bot08, @brkalow, @brvnonascimento, @chanceaclark, @chibicode, @chrisipanaque, @chunsch, @colinking, @craigwheeler, @ctjlewis, @cvolant, @danmindru, @davidnx, @delbaoliveira, @devvspaces, @dtinth, @ducanhgh, @duncanogle, @ethomson, @fantaasm, @feugy, @fomichroman, @gruz0, @haschikeks, @hughlilly, @idoob, @iiegor, @imranbarbhuiya, @ingovals, @inokawa, @ishaqibrahimbot, @ismaelrumzan, @jakemstar, @janicklas-ralph, @jaredpalmer, @jaykch, @jimcresswell, @joliss, @josephcsoti, @joshuaslate, @joulev, @jueungrace, @juliusmarminge, @karlhorky, @kikobeats, @kleintorres, @koenpunt, @koltong, @kosai106, @labyrinthitis, @lachlanjc, @laityned, @leerob, @leoortizz, @lorenzobloedow, @lucasassisrosa, @m7yue, @manovotny, @marcus-rise, @matthew-heath, @mattpr, @maxleiter, @maxproske, @meenie, @mmaaaaz, @mnajdova, @moetazaneta, @mrkldshv, @nathanhammond, @nekochantaiwan, @nfinished, @niedziolkamichal, @nocell, @notrab, @nuta, @nutlope, @obusk, @orionmiz, @peraltafederico, @reshmi-sriram, @reyrodrigez, @rightones, @rishabhpoddar, @saseungmin, @serkanbektas, @sferadev, @silvioprog, @sivtu, @soonoo, @sqve, @steven-tey, @sukkaw, @superbahbi, @teobler, @theevilhead, @thomasballinger, @timeyoutakeit, @valentinh, @ws-jm, @wxh06, @yasath, @yutsuten, and @zekicaneksi.
","description":"Next.js 13.1 includes improvements to both the pages/ (stable) and app/ (beta) directories: app Directory (Beta) Improvements: Improved reliability and performance.\\nBuilt-in Module Transpilation: Bringing next-transpile-modules capabilities into core.\\nEdge Runtime (Stable): A…","guid":"https://nextjs.org/blog/next-13-1","author":null,"authorUrl":null,"authorAvatar":null,"publishedAt":"2022-12-21T16:00:00.342Z","media":null,"categories":null,"attachments":null,"extra":null,"language":null},{"title":"Next.js 13","url":"https://nextjs.org/blog/next-13","content":"As we announced at Next.js Conf, Next.js 13 (stable) lays the foundations to be dynamic without limits:
\\napp
Directory (beta): Easier, faster, less client JS.\\nnext/image
: Faster with native browser lazy loading.@next/font
(beta): Automatic self-hosted fonts with zero layout shift.next/link
: Simplified API with automatic <a>
.Next.js 13 and the pages
directory are stable and ready for production. Update today by running:
npm i next@latest react@latest react-dom@latest eslint-config-next@latest
app
Directory (Beta)Today, we\'re improving the routing and layouts experience in Next.js and aligning with the future of React with the introduction of the app
directory. This is a follow-up to the Layouts RFC previously published for community feedback.
The app
directory is currently in beta and we do not recommend using it in production yet. You can use Next.js 13 with the pages
directory with stable features like the improved next/image
and next/link
components, and opt into the app
directory at your own pace. The pages
directory will continue to be supported for the foreseeable future.
The app
directory includes support for:
async
Server Components and extended fetch
API enables component-level fetching.The app/
directory makes it easy to lay out complex interfaces that maintain state across navigations, avoid expensive re-renders, and enable advanced routing patterns. Further, you can nest layouts, and colocate application code with your routes, like components, tests, and styles.
Creating routes inside app/
requires a single file, page.js
:
// This file maps to the index route (/)\\nexport default function Page() {\\n return <h1>Hello, Next.js!</h1>;\\n}
You can then define layouts through the file system. Layouts share UI between multiple pages. On navigation, layouts preserve state, remain interactive, and do not re-render.
\\nexport default function BlogLayout({ children }) {\\n return <section>{children}</section>;\\n}
Learn more about layouts and pages or deploy an example to try it out.
\\nThe app/
directory introduces support for React\'s new Server Components architecture. Server and Client Components use the server and the client each for what they\'re best at - allowing you to build fast, highly-interactive apps with a single programming model that provides a great developer experience.
With Server Components, we\'re laying the foundations to build complex interfaces while reducing the amount of JavaScript sent to the client, enabling faster initial page loads.
\\nWhen a route is loaded, the Next.js and React runtime will be loaded, which is cacheable and predictable in size. This runtime does not increase in size as your application grows. Further, the runtime is asynchronously loaded, enabling your HTML from the server to be progressively enhanced on the client.
\\nLearn more about Server Components or deploy an example to try it out.
\\nThe app/
directory introduces the ability to progressively render and incrementally stream rendered units of the UI to the client.
With Server Components and nested layouts in Next.js, you\'re able instantly render parts of the page that do not specifically require data, and show a loading state for parts of the page that are fetching data. With this approach, the user does not have to wait for the entire page to load before they can start interacting with it.
\\nWhen deployed to Vercel, Next.js 13 applications that use the app/
directory will stream responses by default in both the Node.js and Edge runtimes for improved performance.
Learn more about streaming or deploy an example to try it out.
\\nReact\'s recent Support for Promises RFC introduces a powerful new way to fetch data and handle promises inside components:
\\nasync function getData() {\\n const res = await fetch(\'https://api.example.com/...\');\\n // The return value is *not* serialized\\n // You can return Date, Map, Set, etc.\\n return res.json();\\n}\\n \\n// This is an async Server Component\\nexport default async function Page() {\\n const data = await getData();\\n \\n return <main>{/* ... */}</main>;\\n}
The native fetch
Web API has also been extended in React and Next.js. It automatically dedupes fetch requests and provides one flexible way to fetch, cache, and revalidate data at the component level. This means all the benefits of Static Site Generation (SSG), Server-Side Rendering (SSR), and Incremental Static Regeneration (ISR) are now available through one API:
// This request should be cached until manually invalidated.\\n// Similar to `getStaticProps`.\\n// `force-cache` is the default and can be omitted.\\nfetch(URL, { cache: \'force-cache\' });\\n \\n// This request should be refetched on every request.\\n// Similar to `getServerSideProps`.\\nfetch(URL, { cache: \'no-store\' });\\n \\n// This request should be cached with a lifetime of 10 seconds.\\n// Similar to `getStaticProps` with the `revalidate` option.\\nfetch(URL, { next: { revalidate: 10 } });
In the app
directory, you can fetch data inside layouts, pages, and components – including support for streaming responses from the server.
We\'re enabling ergonomic ways to handle loading and error states and stream in UI as it\'s rendered. In a future release, we\'ll be improving and simplifying data mutations, as well.
\\nWe\'re excited to work with the open-source community, package maintainers, and other companies contributing to the React ecosystem to build for this new era of React and Next.js. The ability to colocate data fetching inside components and ship less JavaScript to the client were two important pieces of community feedback we are excited to include with the app/
directory.
Learn more about data fetching or deploy an example to try it out.
\\nNext.js 13 includes Turbopack, the new Rust-based successor to Webpack.
\\nWebpack has been downloaded over 3 billion times. While it\'s been an integral part of building the Web, we\'ve hit the limits of the maximum performance possible with JavaScript-based tooling.
\\nIn Next.js 12, we began our transition to native Rust-powered tooling. We started by migrating away from Babel, which resulted in 17x faster transpilation. Then, we replaced Terser, which resulted in 6x faster minification. It\'s time to go all-in on native for bundling.
\\nUsing the Turbopack alpha with Next.js 13 results in:
\\nTurbopack only bundles the minimum assets required in development, so startup time is extremely fast. On an application with 3,000 modules, Turbopack takes 1.8 seconds to boot up. Vite takes 11.4 seconds and Webpack takes 16.5 seconds.
\\nTurbopack has out-of-the-box support for Server Components, TypeScript, JSX, CSS, and more. During the alpha, many features are not yet supported. We\'d love to hear your feedback on using Turbopack to speed up your local iterations.
\\n\\n\\nNote: Turbopack in Next.js currently only supports
\\nnext dev
. View the supported features. We are also working to add support fornext build
through Turbopack.
Try out the Turbopack alpha today in Next.js 13 with next dev --turbo
.
next/image
Next.js 13 introduces a powerful new Image component, allowing you to easily display images without layout shift and optimize files on-demand for increased performance.
\\nDuring the Next.js Community Survey, 70% of respondents told us they used the Next.js Image component in production, and in turn, saw improved Core Web Vitals. With Next.js 13, we\'re improving next/image
even further.
The new Image component:
\\nalt
tags by defaultimport Image from \'next/image\';\\nimport avatar from \'./lee.png\';\\n \\nexport default function Home() {\\n // \\"alt\\" is now required for improved accessibility\\n // optional: image files can be colocated inside the app/ directory\\n return <Image alt=\\"leeerob\\" src={avatar} placeholder=\\"blur\\" />;\\n}
Learn more about the Image component or deploy an example to try it out.
\\nnext/image
to Next.js 13The old Image component was renamed to next/legacy/image
. We\'ve provided a codemod that will automatically update your existing usage of next/image
to next/legacy/image
. For example, this command would run the codemod on your ./pages
directory when run from the root:
npx @next/codemod next-image-to-legacy-image ./pages
@next/font
Next.js 13 introduces a brand new font system that:
\\nsize-adjust
propertyThis new font system allows you to conveniently use all Google Fonts with performance and privacy in mind. CSS and font files are downloaded at build time and self-hosted with the rest of your static assets. No requests are sent to Google by the browser.
\\nimport { Inter } from \'@next/font/google\';\\n \\nconst inter = Inter();\\n \\n<html className={inter.className}></html>;
Custom fonts are also supported, including support for automatic self-hosting, caching, and preloading of font files.
\\nimport localFont from \'@next/font/local\';\\n \\nconst myFont = localFont({ src: \'./my-font.woff2\' });\\n \\n<html className={myFont.className}></html>;
You can customize every part of the font loading experience while still ensuring great performance and no layout shift, including the font-display
, preloading, fallbacks, and more.
Learn more about the new Font component or deploy an example to try it out.
\\nnext/link
next/link
no longer requires manually adding <a>
as a child.
This was added as an experimental option in 12.2 and is now the default. In Next.js 13, <Link>
always renders an <a>
and allows you to forward props to the underlying tag. For example:
import Link from \'next/link\'\\n \\n// Next.js 12: `<a>` has to be nested otherwise it\'s excluded\\n<Link href=\\"/about\\">\\n <a>About</a>\\n</Link>\\n \\n// Next.js 13: `<Link>` always renders `<a>`\\n<Link href=\\"/about\\">\\n About\\n</Link>
Learn more about the improved Link component or deploy an example to try it out.
\\nnext/link
to Next.js 13To upgrade your links to Next.js 13, we\'ve provided a codemod that will automatically update your codebase. For example, this command would run the codemod on your ./pages
directory when run from the root:
npx @next/codemod new-link ./pages
Learn more about the codemod or check out the documentation.
\\nSocial cards, also known as open graph images, can massively increase the engagement rate of clicks on your content, with some experiments showing up to 40% better conversions.
\\nStatic social cards are time-consuming, error-prone, and hard to maintain. Because of this, social cards are often lacking or even skipped. Until today, dynamic social cards that need to be personalized and computed on the fly were difficult and expensive.
\\nWe\'ve created a new library @vercel/og
that works seamlessly with Next.js to generate dynamic social cards.
import { ImageResponse } from \'@vercel/og\';\\n \\nexport const config = {\\n runtime: \'experimental-edge\',\\n};\\n \\nexport default function () {\\n return new ImageResponse(\\n (\\n <div\\n style={{\\n display: \'flex\',\\n fontSize: 128,\\n background: \'white\',\\n width: \'100%\',\\n height: \'100%\',\\n }}\\n >\\n Hello, World!\\n </div>\\n ),\\n );\\n}
This approach is 5x faster than existing solutions by using Vercel Edge Functions, WebAssembly, and a brand new core library for converting HTML and CSS into images and leveraging the React component abstraction.
\\nLearn more about OG Image Generation or deploy an example to try it out.
\\nIn Next.js 12, we introduced Middleware to enable full flexibility with the Next.js router. We\'ve heard your feedback on the initial API design and have added some additions to improve the developer experience and add powerful new functionality.
\\nYou can now more easily set headers on the request:
\\nimport { NextResponse } from \'next/server\';\\nimport type { NextRequest } from \'next/server\';\\n \\nexport function middleware(request: NextRequest) {\\n // Clone the request headers and set a new header `x-version`\\n const requestHeaders = new Headers(request.headers);\\n requestHeaders.set(\'x-version\', \'13\');\\n \\n // You can also set request headers in NextResponse.rewrite\\n const response = NextResponse.next({\\n request: {\\n // New request headers\\n headers: requestHeaders,\\n },\\n });\\n \\n // Set a new response header `x-version`\\n response.headers.set(\'x-version\', \'13\');\\n return response;\\n}
You can also now provide a response directly from Middleware, without having to rewrite
or redirect
.
import { NextRequest, NextResponse } from \'next/server\';\\nimport { isAuthenticated } from \'@lib/auth\';\\n \\n// Limit the middleware to paths starting with `/api/`\\nexport const config = {\\n matcher: \'/api/:function*\',\\n};\\n \\nexport function middleware(request: NextRequest) {\\n // Call our authentication function to check the request\\n if (!isAuthenticated(request)) {\\n // Respond with JSON indicating an error message\\n return NextResponse.json(\\n {\\n success: false,\\n message: \'Auth failed\',\\n },\\n {\\n status: 401,\\n },\\n );\\n }\\n}
Sending responses from Middleware currently requires the experimental.allowMiddlewareResponseBody
configuration option inside next.config.js
.
swcMinify
configuration property was changed from false
to true
. See Next.js Compiler for more info.next/image
import was renamed to next/legacy/image
. The next/future/image
import was renamed to next/image
. A codemod is available to safely and automatically rename your imports.next/link
child can no longer be <a>
. Add the legacyBehavior
prop to use the legacy behavior or remove the <a>
to upgrade. A codemod is available to automatically upgrade your code.User-Agent
is a bot.target
option of next.config.js
has been removed.To learn more, check out the upgrade guide.
\\nSix years ago, we released Next.js to the public. We set out to build a zero-configuration React framework that simplifies your developer experience. Looking back, it\'s incredible to see how the community has grown, and what we\'ve been able to ship together. Let\'s keep going.
\\nNext.js is the result of the combined work of over 2,400 individual developers, industry partners like Google and Meta, and our core team. With over 3 million npm downloads per week and 94,000 GitHub stars, Next.js is one of the most popular ways of building the Web.
\\nSpecial thanks to the Aurora team at Google Chrome who helped with the foundational research and experiments that led to this release.
\\nThis release was brought to you by the contributions of: @ijjk, @huozhi, @HaNdTriX, @iKethavel, @timneutkens, @shuding, @rishabhpoddar, @hanneslund, @balazsorban44, @devknoll, @anthonyshew, @TomerAberbach, @philippbosch, @styfle, @mauriciomutte, @hayitsdavid, @abdennor, @Kikobeats, @cjdunteman, @Mr-Afonso, @kdy1, @jaril, @abdallah-nour, @North15, @feedthejim, @brunocrosier, @Schniz, @sedlukha, @hashlash, @Ethan-Arrowood, @fireairforce, @migueloller, @leerob, @janicklas-ralph, @Trystanr, @atilafassina, @nramkissoon, @kasperadk, @valcosmos, @henriqueholtz, @nip10, @jesstelford, @lorensr, @AviAvinav, @SukkaW, @jaycedotbin, @saurabhburade, @notrab, @kwonoj, @sanruiz, @angeloashmore, @falsepopsky, @fmontes, @Gebov, @UltiRequiem, @p13lgst, @Simek, @mrkldshv, @thomasballinger, @kyliau, @AdarshKonchady, @endymion1818, @pedro757, @perkinsjr, @gnoff, @jridgewell, @silvioprog, @mabels, @nialexsan, @feugy, @jackromo888, @crazyurus, @EarlGeorge, @MariaSolOs, @lforst, @maximbaz, @maxam2017, @teobler, @Nutlope, @sunwoo0706, @WestonThayer, @Brooooooklyn, @Nsttt, @charlypoly, @aprendendofelipe, @sviridoff, @jackton1, @nuta, @Rpaudel379, @marcialca, @MarDi66, @ismaelrumzan, @javivelasco, @eltociear, and @hiro0218.
","description":"As we announced at Next.js Conf, Next.js 13 (stable) lays the foundations to be dynamic without limits: app Directory (beta): Easier, faster, less client JS.\\nLayouts\\nReact Server Components\\nStreaming\\nTurbopack (alpha): Up to 700x faster Rust-based Webpack replacement.\\nNew nex…","guid":"https://nextjs.org/blog/next-13","author":null,"authorUrl":null,"authorAvatar":null,"publishedAt":"2022-10-24T16:00:00.896Z","media":[{"url":"https://nextjs.org/_next/image?url=https%3A%2F%2Fh8DxKfmAPhn8O0p3.public.blob.vercel-storage.com%2Fstatic%2Fblog%2Flayouts-rfc%2Fapp-folder.png&w=3840&q=75","type":"photo","width":3596,"height":1534},{"url":"https://nextjs.org/_next/image?url=https%3A%2F%2Fh8DxKfmAPhn8O0p3.public.blob.vercel-storage.com%2Fstatic%2Fblog%2Fnext-13%2Fcolocating-assets-in-the-app-directory.png&w=3840&q=75","type":"photo","width":3596,"height":1534},{"url":"https://nextjs.org/_next/image?url=https%3A%2F%2Fh8DxKfmAPhn8O0p3.public.blob.vercel-storage.com%2Fstatic%2Fblog%2Fnext-13%2Fstreaming.png&w=3840&q=75","type":"photo","width":3600,"height":1648},{"url":"https://nextjs.org/_next/image?url=https%3A%2F%2Fh8DxKfmAPhn8O0p3.public.blob.vercel-storage.com%2Fstatic%2Fblog%2Fnext-13%2Fstreaming.png&w=3840&q=75","type":"photo","width":3596,"height":1980},{"url":"https://nextjs.org/_next/image?url=https%3A%2F%2Fh8DxKfmAPhn8O0p3.public.blob.vercel-storage.com%2Fstatic%2Fblog%2Fnext-13%2Fturbopack.png&w=3840&q=75","type":"photo","width":2046,"height":720}],"categories":null,"attachments":null,"extra":null,"language":null},{"title":"Next.js 12.3","url":"https://nextjs.org/blog/next-12-3","content":"We\'ve shipped some quality-of-life improvements to Next.js with 12.3:
\\n.env
, jsconfig.json
, and tsconfig.json
files now hot reload..ts
file to automatically configure TypeScript and install deps.next/future/image
is now stable.Update today by running npm i next@latest
.
\\n\\nAnnouncing the third global Next.js community conference on October 25th. Register now →
\\n
You’re invited to the global Next.js community conference on October 25th. For the 6th anniversary of Next.js, we’ll be introducing:
\\nClaim your free ticket and see the future of Next.js and React, and follow @nextjs for more announcements soon. We’re also looking for community talks. Submit a talk proposal and share the story of what you’re building with Next.js.
\\nNext.js has built-in support for automatically configuring TypeScript. Previously, adding TypeScript to an existing project required manually installing the necessary dependencies.
\\nWith this release, Next.js automatically detects when TypeScript files are added to a project, installs the necessary dependencies, and adds a tsconfig.json
file. This works when running next dev
and next build
.
Fast iterations are critical for your local development workflow. Next.js uses Fast Refresh for instantaneous feedback on edits made to your React components. Hit save and see your changes reflected in the browser without needing to reload the page.
\\nWith Next.js 12.3, some configuration files now also hot reloaded when making edits, including:
\\n.env
and env.*
variantsjsconfig.json
tsconfig.json
You now do not need to restart your local development server when making changes to these configuration files.
\\nnext/future/image
component (Stable)\\n \\n \\n \\n \\nIn Next.js 12.2, we shared an experimental preview of a new Image component that simplifies how you style images and improves performance by using native browser lazy loading.
\\nThe new Image component is now stable and no longer requires an experimental flag.
\\nSince the last release, we\'ve made further improvements:
\\nfill
layout mode that causes the image to fill the parent element.<noscript>
, and next dev
matches next start
.alt
text while image is loading.alt
property for better accessibility.onError
property when error occurs before hydration.width
or only height
property.In the future, we plan to rename next/image
to next/legacy/image
and next/future/image
to next/image
. This will provide a great experience for new Next.js projects and existing projects will be able to easily migrate using our next/image
codemod. We will provide more details leading up to the next major version.
For more information on how to use it today, please refer to the documentation which includes a migration guide.
\\nremotePatterns
allows you to specify wildcards for remote images when using the built-in Image Optimization API. It allows for more powerful matching beyond the existing images.domains
configuration, which only performs exact matches on the domain name.
This option is now stable and can be used with the following configuration option:
\\nmodule.exports = {\\n images: {\\n remotePatterns: [\\n {\\n // The `src` property hostname must end with `.example.com`,\\n // otherwise the API will respond with 400 Bad Request.\\n protocol: \'https\',\\n hostname: \'**.example.com\',\\n },\\n ],\\n },\\n};
The Image Optimization API requires a server to optimize images on demand as they’re requested. This works great when self-hosting with next start
or deploying to platforms like Vercel. However, this won\'t work with next export
because it doesn’t include a server to optimize images. Previously, you would need to configure a 3rd party Image Optimization provider using the loader
prop, but now you can disable Image Optimization completely using next.config.js
for all instances of next/image
.
This previously experimental option is now stable and can be used with the following configuration option:
\\nmodule.exports = {\\n images: {\\n unoptimized: true,\\n },\\n};
In Next.js 12, we introduced code minification using SWC as part of the experimental features of Next.js Compiler. Early results showed that minification with SWC was 7x faster than the previous version with Terser.
\\nWith this release, the feature is stable and you can opt-in using the following next.config.js
option:
module.exports = {\\n swcMinify: true,\\n};
We plan to make the SWC minifier the default in the next major version.
\\nEarlier this year, we published the Layouts RFC which introduced the biggest update to Next.js since it was released in 2016. These changes include a new router built on top of React Server Components. The implementation work has begun and we’re working towards a public beta in the next major version.
\\nToday, we’re sharing more information about upcoming features, including:
\\nAdditionally, in a different RFC, we\'re exploring adding support for Global CSS Imports in the new app
directory . This would allow you to use packages that import their own .css
files without additional configuration.
Read more about these new features in the Layouts RFC.
\\ncreate-next-app
templates now include dark mode support automatically using your system preference.src/
is now a default linting directory when using the integrated ESLint support.next.config.js
now includes schema validation with ajv
, helping prevent misuse of configuration options.next.config.js
now has an experimental config flag fallbackNodePolyfills: false
to prevent Next.js from polyfilling Node.js APIs for the browser (which leads to increased bundle sizes). This option will cause Next.js to show a build-time error showing where the unnecessary import comes from.Next.js is the result of the combined work of over 2,000 individual developers, industry partners like Google Chrome and Meta, and our core team at Vercel.
\\nThis release was brought to you by the contributions of: @pthomas931, @madmed88, @sanjaiyan-dev, @balazsorban44, @DonghyukJacobJang, @chaiwattsw, @styfle, @dunglas, @ahkhanjani, @promer94, @terrierscript, @shawncal, @insik-han, @QuiiBz, @ykzts, @JoshuaKGoldberg, @lucasassisrosa, @dikwickley, @Brooooooklyn, @sicarius97, @FourwingsY, @manovotny, @SukkaW, @pepoeverton, @jdeniau, @sumiren, @anthonyshew, @pekarja5, @huozhi, @leerob, @fediev, @atcastle, @shuding, @feugy, @jonohewitt, @zakiego, @Schniz, @timneutkens, @wyattjoh, @MaedahBatool, @X7Becka, @nnnnoel, @dcdev67, @alvinometric, @timothympace, @jeferson-sb, @ijjk, @theMosaad, @Yuddomack, @msquitieri, @andreizanik, @nix6839, @thomasballinger, @ziishaned, @xyeres, @nyedidikeke, @maxproske, @sokra, @titusdmoore, @thebergamo, @fikrikarim, @Kikobeats, @clearlyTHUYDOAN, @nasso, @qutek, @kdy1, @kyliau, @housseindjirdeh, @barissayil, @seveibar, @Jessidhia, @santidalmasso, @JohnDaly, @Nikhilnama18, @mduleone, @colinhacks, @ductnn, @josh, @hiro0218, @eltociear, @kwonoj, @valcosmos, @mihaic195, @stefanprobst, @KATT, @thiagomorales, @danielcavanagh, @steven-tey, @hellomhc, @trevor-fauna, @nguyenyou, @eminvergil, @lobsterkatie, @dorian-davis, @sambecker, @isaac-martin, @lfades, @amorimr, @javivelasco, @mongolyy, @Thisen, @zorrolisto, @ethomson, @padmaia, @thisisjofrank, @dominiksipowicz, @awareness481, @pakaponk, @apledger, @longzheng, @tknickman, @rbrcsk, @emersonlaurentino, @carstenlebek, @edusig, @riccardogiorato, @hanneslund, @ryanhaticus, @j-mendez, @armandabric, @WinmezzZ, @andershagbard, @dammy001, @MarDi66, @okmttdhr, @rishabhpoddar, @marjorg, @dustinsgoodman, and @zanechua.
","description":"We\'ve shipped some quality-of-life improvements to Next.js with 12.3: Improved Fast Refresh: .env, jsconfig.json, and tsconfig.json files now hot reload.\\nTypeScript Auto-Install: Add a .ts file to automatically configure TypeScript and install deps.\\nImage Component: next/future…","guid":"https://nextjs.org/blog/next-12-3","author":null,"authorUrl":null,"authorAvatar":null,"publishedAt":"2022-09-07T16:00:00.224Z","media":[{"url":"https://assets.vercel.com/video/upload/v1662616608/nextjs/blog/ts-autoinstall.mp4","type":"video","width":640,"height":360},{"url":"https://assets.vercel.com/video/upload/v1662616591/nextjs/blog/fast-refresh.mp4","type":"video","width":640,"height":360}],"categories":null,"attachments":null,"extra":null,"language":null},{"title":"Next.js 12.2","url":"https://nextjs.org/blog/next-12-2","content":"We\'re laying the foundation for the future of Next.js with 12.2:
\\nnext/image
: Including a new next/future/image
component.Update today by running npm i next@latest
.
We\'re excited to announce Middleware is now stable in 12.2 and has an improved API based on feedback from users.
\\nMiddleware allows you to run code before a request is completed. Based on the incoming request, you can modify the response by rewriting, redirecting, adding headers, or setting cookies.
\\nimport { NextRequest, NextResponse } from \'next/server\';\\n \\n// If the incoming request has the \\"beta\\" cookie\\n// then we\'ll rewrite the request to /beta\\nexport function middleware(req: NextRequest) {\\n const isInBeta = JSON.parse(req.cookies.get(\'beta\') || \'false\');\\n req.nextUrl.pathname = isInBeta ? \'/beta\' : \'/\';\\n return NextResponse.rewrite(req.nextUrl);\\n}\\n \\n// Supports both a single value or an array of matches\\nexport const config = {\\n matcher: \'/\',\\n};
To update to the newest API changes for Middleware, please see the migration guide.
\\nTry Middleware for free on Vercel or when self-hosting using next start
.
On-Demand Incremental Static Regeneration (ISR) allows you to update the content on your site without needing to redeploy. This makes it easy to update your site immediately when data changes in your headless CMS or commerce platform. This was one of the most requested features from the community and we\'re excited it is now stable.
\\nexport default async function handler(req, res) {\\n // Check for secret to confirm this is a valid request\\n if (req.query.secret !== process.env.MY_SECRET_TOKEN) {\\n return res.status(401).json({ message: \'Invalid token\' });\\n }\\n \\n try {\\n await res.revalidate(\'/path-to-revalidate\');\\n return res.json({ revalidated: true });\\n } catch (err) {\\n // If there was an error, Next.js will continue\\n // to show the last successfully generated page\\n return res.status(500).send(\'Error revalidating\');\\n }\\n}
Incremental Static Regeneration works for any providers supporting the Next.js Build API (next build
). When deployed to Vercel, on-demand revalidation propagates globally in ~300ms when pushing pages to the edge.
For more information, check out the documentation or view our demo to see on-demand revalidation in action.
\\nNext.js now also supports using the Edge Runtime for API Routes. The Edge Runtime is a lighter-weight runtime than Node.js providing fast startups for low latency. In addition, Edge API Routes support streaming responses from the server.
\\nYou can set the runtime for an API Route in the config
, specifying either nodejs
(default) or experimental-edge
:
import type { NextRequest } from \'next/server\';\\n \\nexport default (req: NextRequest) => {\\n return new Response(`Hello, from ${req.url} I\'m now an Edge API Route!`);\\n};\\n \\nexport const config = {\\n runtime: \'experimental-edge\',\\n};
Because the Edge Runtime is lightweight, it has limitations to accommodate fast startup — for example, it does not support Node.js-specific APIs like fs
. Therefore, the default runtime for API Routes remains nodejs
.
For more information, check out the documentation.
\\nNext.js now supports using the Edge Runtime for server rendering.
\\nAs mentioned above, the Edge Runtime is a lighter-weight runtime than Node.js providing fast startups for low latency. When used with React 18, it enables streaming server-rendering for Pages.
\\nNext.js uses Node.js as the default runtime for server-side rendering pages. Starting with 12.2, if you are using React 18 you can opt into using the Edge Runtime.
\\nYou can set the runtime globally in next.config.js
, specifying either nodejs
or experimental-edge
:
module.exports = {\\n experimental: {\\n runtime: \'experimental-edge\',\\n },\\n};
Changing the default page runtime affects all pages, including SSR streaming and Server Components features. You can also override this default on a per-page basis, by exporting a runtime
config:
export const config = {\\n runtime: \'nodejs\',\\n};\\n \\nexport default function Home() {}
You can detect which runtime you\'re using by looking at the process.env.NEXT_RUNTIME
Environment Variable during runtime, and examining the options.nextRuntime
variable during webpack compilation.
For more information, check out the documentation.
\\nnext/image
\\n \\n \\n \\n \\nnext/future/image
component (Experimental)\\n \\n \\n \\n \\nWe\'ve heard your feedback on the current Image component and are excited to share an early preview of the new next/image
. This new and improved image component requires less client-side JavaScript and simplifies how you style images:
<img>
without <div>
or <span>
wrappersstyle
proplayout
, objectFit
, and objectPosition
props in favor of style
or className
IntersectionObserver
implementation in favor of native lazy loadingloader
config in favor of loader
propfill
mode (yet) so width
& height
props are requiredThis improves performance because native loading=\\"lazy\\"
doesn\'t need to wait for React hydration and client-side JavaScript.
For more information, check out the documentation.
\\nnext/image
now supports an experimental configuration option remotePatterns
that allows you to specify wildcards for remote images when using the built-in Image Optimization API. This allows for more powerful matching beyond the existing images.domains
configuration, which only performs exact matches on the domain name.
module.exports = {\\n experimental: {\\n images: {\\n remotePatterns: [\\n {\\n // The `src` property hostname must end with `.example.com`,\\n // otherwise this will respond with 400 Bad Request.\\n protocol: \'https\',\\n hostname: \'**.example.com\',\\n },\\n ],\\n },\\n },\\n};
For more information, check out the documentation.
\\nThe zero-config Image Optimization API prevents the use of next export
since it requires a server to optimize images on-demand as they\'re requested. Until today, users targeting next export
needed to configure the loader
to use a 3rd party Image Optimization provider, but there was no clear solution if there was no provider available. Starting today, next export
users can disable Image Optimization for all instances of next/image
with a new configuration property:
module.exports = {\\n experimental: {\\n images: {\\n unoptimized: true,\\n },\\n },\\n};
The Next.js Compiler uses SWC to transform and minify your JavaScript code for production. SWC was introduced in Next.js 12.0 to improve both local development and build performance.
\\nYou can now add plugins (written in WebAssembly) to customize the SWC transformation behavior during compilation:
\\nmodule.exports = {\\n experimental: {\\n swcPlugins: [\\n [\'css-variable/swc\', { displayName: true, basePath: __dirname }],\\n ],\\n },\\n};
For more information, check out the documentation.
\\nstyled-components
and emotion
with a smoother upgrade experience and no breaking changes.next/head
now supports React 18.@emotion/babel-plugin
are now supported, and unless you are using importMap
, it can be removed. For more information, check out the documentation.styled-components
transform in the Next.js Compiler by allowing customization of the default options, including the cssProp
option. For more information, check out the documentation.next/image
and next/link
can properly be import
ed.next/link
no longer requires manually adding <a>
as a child. You can now opt into this behavior in a backward-compatible way.browsersList
. You can opt-into this behavior by setting browsersListForSwc: true
and legacyBrowsers: false
in the experimental
option of next.config.js
.@swc/helpers
optimizations prevent duplication across bundles, reducing bundle size by around 2KB
in a minimal configuration, and more on larger appspnpm
, which allows us to remove duplicate packages while creating the pre-compiled versions that we use. This leads to a reduction in install size of 14MB.outputStandalone: true
config to output: \'standalone\'
. This config reduces deployment sizes drastically by only including necessary files/assets, including removing the need for installing all of node_modules
in the built deployment package. This config can be seen in action in our with-docker
example.In case you missed it, last month we announced the Layouts RFC – the biggest update to Next.js since it was introduced in 2016 including:
\\nFor more information, check out the RFC or provide feedback.
\\nNext.js is the result of the combined work of over 2,000 individual developers, industry partners like Google Chrome and Meta, and our core team at Vercel.
\\nThis release was brought to you by the contributions of: @huozhi, @ijjk, @kwonoj, @ViolanteCodes, @akrabdev, @timneutkens, @jpveilleux, @stigkj, @jgoping, @oof2win2, @Brooooooklyn, @CGamesPlay, @lfades, @molebox, @steven-tey, @SukkaW, @Kikobeats, @balazsorban44, @erikbrinkman, @therealmarzouq, @remcohaszing, @perkinsjr, @shuding, @hanneslund, @housseindjirdeh, @RobertKeyser, @styfle, @htunnicliff, @lukeshumard, @sagnik3, @pixelass, @JoshuaKGoldberg, @rishabhpoddar, @nguyenyou, @kdy1, @sidwebworks, @gnoff, @gaspar09, @feugy, @mfix-stripe, @javivelasco, @Chastrlove, @goncharov-vlad, @NaveenDA, @Firfi, @idkwhojamesis, @FLCN-16, @icyJoseph, @ElijahPepe, @elskwid, @irvile, @Munawwar, @ykolbin, @hulufei, @baruchadi, @imadatyatalah, @await-ovo, @menosprezzi, @gazs, @Exortions, @rubens-lopes, @woochul2, @stefee, @stmtk1, @jlarmstrongiv, @MaedahBatool, @jameshfisher, @fabienheureux, @TxHawks, @mattbrandlysonos, @iggyzap, @src200, @AkifumiSato, @hermanskurichin, @kamilogorek, @ben-xD, @dawsonbooth, @Josehower, @crutchcorn, @ericmatthys, @CharlesStover, @charlypoly, @apmatthews, @naingaungphyo, @alexandrutasica, @stefanprobst, @dc7290, @DilwoarH, @tommarshall, @stanhong, @leerob, @appsbytom, @sshyam-gupta, @saulloalmeida, @indicozy, @ArianHamdi, @Clariity, @sebastianbenz, @7iomka, @gr-qft, @Schniz, @dgagn, @sokra, @okbel, @tbvjaos510, @dmvjs, @PepijnSenders, @JohnPhamous, @kyliau, @eric-burel, @alabhyajindal, @jsjoeio, @vorcigernix, @clearlyTHUYDOAN, @splatterxl, @manovotny, @maxproske, @nvh95, @frankievalentine, @nuta, @bagpyp, @dfelsie, @qqpann, @atcastle, @jsimonrichard, @mass2527, @ekamkohli, @Yuddomack, @tonyspiro, @saurabhmehta1601, @banner4422, @falsepopsky, @jantimon, @henriqueholtz, @ilfa, @matteobruni, @ryscheng, @hoonoh, @ForsakenHarmony, @william-keller, @AleksaC, @Miikis, @zakiego, @radunemerenco, @AliYusuf95, and @dominiksipowicz.
","description":"We\'re laying the foundation for the future of Next.js with 12.2: Middleware (Stable): Dynamic routing for your entire application.\\nOn-Demand ISR (Stable): Update content without redeploying.\\nEdge API Routes (Experimental): High performance API endpoints.\\nEdge SSR (Experimental):…","guid":"https://nextjs.org/blog/next-12-2","author":null,"authorUrl":null,"authorAvatar":null,"publishedAt":"2022-06-27T16:00:00.324Z","media":null,"categories":null,"attachments":null,"extra":null,"language":null},{"title":"Next.js 12.1","url":"https://nextjs.org/blog/next-12-1","content":"We\'re excited to release one of our most requested features with Next.js 12.1:
\\ngetStaticProps
instantly.styled-components
, Relay, and more.next/jest
Plugin: Zero-configuration Jest support using SWC.Update today by running npm i next@latest
.
Next.js now exposes a function unstable_revalidate()
allowing you to revalidate individual pages that use getStaticProps
. This was one of our most requested features since we introduced Incremental Static Regeneration (ISR) in Next.js 9.5.
Since ISR was released, we\'ve seen companies like Tripadvisor, Parachute, HashiCorp, and more drastically improve their build times while retaining incredible performance. However, we\'ve heard your feedback on interval-based revalidations and are excited to provide more flexibility.
\\nCurrently, if you set a revalidate
time of 60
, all visitors will see the same generated version of your site for one minute. The only way to invalidate the cache was from someone visiting that page after the minute had passed. You can now manually purge the Next.js cache for a specific page on-demand.
This makes it easier to update your site when:
\\nexport default async function handler(req, res) {\\n // Check for secret to confirm this is a valid request\\n if (req.query.secret !== process.env.MY_SECRET_TOKEN) {\\n return res.status(401).json({ message: \'Invalid token\' });\\n }\\n \\n try {\\n await res.unstable_revalidate(\'/path-to-revalidate\');\\n return res.json({ revalidated: true });\\n } catch (err) {\\n // If there was an error, Next.js will continue\\n // to show the last successfully generated page\\n return res.status(500).send(\'Error revalidating\');\\n }\\n}
Inside getStaticProps
, you do not need to specify revalidate
to use on-demand revalidation. If revalidate
is omitted, Next.js will use the default value of false
(no revalidation) and only revalidate the page on-demand when unstable_revalidate()
is called.
Incremental Static Regeneration works for any providers supporting the Next.js Build API (next build
). Starting today when deployed to Vercel, on-demand revalidation propagates globally in ~300ms when pushing pages to the edge.
View our demo to see on-demand revalidation in action and provide feedback. Svix (enterprise-ready webhooks) and Clerk (authentication) have also created a demo of on-demand ISR.
\\nWe want to make every Next.js application build faster for production and get instant feedback in local development. Next.js 12 introduced a new Rust-based compiler that takes advantage of native compilation.
\\nWith 12.1, we\'ve added support to the Next.js Compiler for:
\\nWith the above six transforms added, we have now ported the most common Babel plugins to Rust using the new compiler. If there are other plugins you\'d like to see, let us know on the discussion. Further, we\'re working on a system for high-performance WebAssembly plugins enabled through SWC.
\\nNext.js now automatically configures Jest for you (next/jest
) using the Rust-based Next.js Compiler to transform files, including:
.css
, .module.css
, and their .scss
variants) and image imports.env
(and all variants) into process.env
node_modules
from test resolving and transforms.next
from test resolvingnext.config.js
for flags that enable Next.js compiler transformsCheck out the documentation to learn more or get started from our Jest example.
\\nWith Next.js 12, we introduced minification using SWC as part of the Next.js Compiler. Early results showed it was 7x faster than Terser. Minification with SWC is now in Release Candidate (RC) with 12.1 and will become the default in 12.2.
\\nYou can opt-in to using SWC for minification in next.config.js
:
module.exports = {\\n swcMinify: true,\\n};
Let us know your feedback on the discussion.
\\nThe built-in Image Optimization API has been updated to support the same pattern as ISR pages, where images are served stale and revalidate in the background (also known as stale-while-revalidate
).
This is a significant performance improvement for optimizing images. See Image Caching Behavior to learn more.
\\nNext.js can now automatically create a standalone
folder that copies only the necessary files for production deployments. This has resulted in ~80% smaller Docker images for self-hosted Next.js applications.
To leverage this automatic copying you can enable it in your next.config.js
:
module.exports = {\\n experimental: {\\n outputStandalone: true,\\n },\\n};
This will create a folder at .next/standalone
which can then be deployed on its own without installing node_modules
.
Check out the documentation or get started from the Docker example. We now also have a multi-env Docker example with support for loading different .env
files based on the environment.
As shown at Next.js Conf, we\'ve been working to bring React 18, Server-Side Suspense, Streaming SSR, and eventually Server Components to Next.js.
\\nServer Components are a new feature in React that let you reduce your JavaScript bundle size by separating server and client-side code. Server Components allow developers to build apps that span the server and client, combining the rich interactivity of client-side apps with the improved performance of traditional server rendering.
\\nFor developers following along on the Server Components path from alpha to beta in Next.js, here are some of the recent updates:
\\nuseId
API in React 18_app
as a Server ComponentWe\'re working to enable you to run your entire Next.js application server-rendered at the Edge. You can choose which pages should opt into the Edge Runtime, so you can incrementally migrate pages from Node.js as you\'re ready.
\\nWe\'ll be releasing another post going more in-depth on the Edge Runtime soon. Both of our demos (next-server-components and next-rsc-demo) have been updated with the latest changes.
\\n<a>
with target=\\"blank\\"
no longer warns to use next/link
with ESLint..d.ts
files are no longer considered Pages.document.title
now takes priority over h1
when announcing page changes to screen readers.pages/index/[...dynamic].js
now works, which previously was not possible due to index
being a reserved keyword.dynamic(() => import(\'./some-component\'), { ssr: false })
the import will be automatically treeshaken from the server code.node-fetch
.styled-jsx
has been upgraded to 5.0, including new helpful error links for all styled-jsx
compilation errors.AbortController
and AbortSignal
CryptoKey
and globalThis.CryptoKey
added.Share your feedback and help us improve Next.js with our first Developer Survey.
\\nThere are two parts to this survey: a quick survey of eight questions and an extended survey that dives into feedback for individual features. We\'d love it if you could fill out both sections if you have time, but if not, feel free to submit your answers after the first section.
\\nYour answers will be completely anonymous, though you can choose to share your app URLs with us if you like.
\\nThanks for helping us improve Next.js!
\\nNext.js is the result of the combined work of over 2,000 individual developers, industry partners like Google and Facebook, and our core team.
\\nTo make contribution easier, we\'ve migrated the Next.js repository to use Turborepo to improve build performance. We\'ve also added scaffolding for tests and error links to make it easier to get started writing tests. Finally, we recorded a 40-minute walkthrough video showing how to contribute to Next.js.
\\nThis release was brought to you by the contributions of: @MaedahBatool, @mutebg, @sokra, @huozhi, @hanford, @shuding, @sean6bucks, @jameshfisher, @devknoll, @yuta-ike, @zh-lx, @amandeepmittal, @alunyov, @stefanprobst, @leerob, @balazsorban44, @kdy1, @brittanyrw, @jord1e, @kara, @vvo, @ismaelrumzan, @dlindenkreuz, @MohammadxAli, @nguyenyou, @thibautsabot, @hanneslund, @vertti, @KateKate, @stefee, @mikinovation, @Leticijak, @mohsen1, @ncphillips, @ehowey, @lancechentw, @krychaxp, @fmacherey, @pklawansky, @RyanClementsHax, @lakbychance, @sannajammeh, @oliviertassinari, @alexander-akait, @u-yas, @Cheprer, @msp5382, @chrispat, @getspooky, @Ryz0nd, @klaasman, @midgleyc, @kumard3, @jesstelford, @neeraj3029, @glenngijsberts, @pie6k, @wouterraateland, @timneutkens, @11koukou, @thesyedbasim, @aeneasr, @ijjk, @lfades, @JuniorTour, @xavhan, @mattyocode, @padmaia, @Skn0tt, @gwer, @Nutlope, @styfle, @stipsan, @xhoantran, @eolme, @sespinosa, @zenorocha, @hjaber, @benmvp, @T-O-R-U-S, @dburrows, @atcastle, @kiriny, @molebox, @Vienio99, @kyliau, @PepijnSenders, @krystofex, @PizzaPete, @souljuse, @Schniz, @Nelsonfrank, @Mhmdrza, @hideokamoto-stripe, @Emrin, @gr-qft, @delbaoliveira, @redbar0n, @lxy-yz, @Divlo, @kachkaev, @teleaziz, @OgbeniHMMD, @goncy, @bennettdams, @hsynlms, @callumgare, @jonrosner, @karaggeorge, @rpie3, @MartijnHols, @bashunaimiroy, @NOCELL, @rishabhpoddar, @omariosouto, @theMosaad, @javivelasco, @pierrenel, @lobsterkatie, @tharakabimal, @saevarb, @nbouvrette, @paulnbrd, @ecklf, @renbaoshuo, @chozzz, @tbezman, @karlhorky, @j-mendez, @ffan0811, @arthurfiorette, @chimit, @joperron, @moh12594, @rasmusjp, @bryanrsmith, @TrySound, @josharsh, @thecrypticace, @arturparkhisenko, @segheysens, @thevinter, @AryanBeezadhur, @xiaohp, @tknickman, @oriolcp, @smakosh, @jorrit, @mix3d, @Clecio013, @michielvangendt, @intergalacticspacehighway, @jbraithwaite, @marcelocarmona, @benmerckx, @haykerman, @steven-tey, @jaredpalmer, @pi-guy-in-the-sky, @JuanM04, @apollisa, @D-Pagey, @Kikobeats, @ramosbugs, @dan-weaver, @chris-stytch, @MikevPeeren, @janpio, @emw3, @nubpro, @cmdcolin, @joostdecock, @sgallese, @housseindjirdeh, @minervabot, @cjboco, @Ryuurock, @dm430, @mkarkachov, @nvh95, @gfortaine, @zifeo, @vicente-s, @Rohithgilla12, @brookton, @skirsten, @davidfateh, @DavidBabel, @mannybecerra, @pveyes, @kaykdm, @xhiroga, @mzaien, @losfair, @ykzts, @knezevicdev, @yang-feng-yfeng, @xuchaobei, @elkevinwolf, @fabienheureux, @nilskaspersson, @Andarist, @mathcrln, @dferber90, @FranciscoMoretti, @benschwarz, @wendellhu95, @gazdagergo, @imabp, @ljosberinn, @samuliasmala, @ka2jun8, @monsonjeremy, @pqt, @leoortizz, @michel-kraemer, @ntkoopman, @iicdii, @chentsulin, @ericmatthys, @lennym, @balogunkeji, @wnr, @chemicalkosek, @KittyGiraudel, @OKinane, @KonstHardy, @BrandonRomano, @furcan, @dusanralic, @elliottsj, @hi-ogawa, @panva, @genetschneider, @thundermiracle, @stefano-rainieri, @ericbiewener, @vordgi, @stevejarvis, @ihmpavel, @matamatanot, @dyarfaradj, @iheyunfei, @ascorbic, @fytriht, @emzoumpo, @onurtemiz, @a-ursino, @mxschmitt, @bywo, @OArnarsson, @TurekBot, @gish, @vadymshymko, @kamsar, @skhaz, @Prashoon123, @IrisvanOllefen, @evan-bradley, @ntltd, @EzequielDM, @oBusk, @martpie, @BruceRodrigues, @luke-h1, @lucasvazq, @velocity23, @AkiraTsuboi, @mitheelgajare, @JamiesWhiteShirt, @leroydev, @JulienZD, @leotaku, @mattfwood, and @kripod.
","description":"We\'re excited to release one of our most requested features with Next.js 12.1: On-demand ISR (Beta): Revalidate pages using getStaticProps instantly.\\nExpanded Support for SWC: styled-components, Relay, and more.\\nnext/jest Plugin: Zero-configuration Jest support using SWC.\\nFaster…","guid":"https://nextjs.org/blog/next-12-1","author":null,"authorUrl":null,"authorAvatar":null,"publishedAt":"2022-02-16T16:00:00.045Z","media":null,"categories":null,"attachments":null,"extra":null,"language":null},{"title":"Next.js 12","url":"https://nextjs.org/blog/next-12","content":"As we announced at Next.js Conf, Next.js 12 is our biggest release ever:
\\n<Image />
AVIF Support: Opt-in for 20% smaller imagesUpdate today by running npm i next@latest
.
We want to make every Next.js application build faster for production, and get instant feedback in local development. Next.js 12 includes a brand new Rust compiler that takes advantage of native compilation.
\\nOur Rust compiler is built on SWC, an open platform for the next generation of fast tooling. We\'ve optimized bundling and compiling with ~3x faster refresh locally and ~5x faster builds for production. Other improvements and features include:
\\nCompilation using Rust is 17x faster than Babel and enabled by default using Next.js 12, replacing transforming JavaScript and TypeScript files. This meant we had to port the Babel transformations in Next.js to Rust, including a brand new CSS parser in Rust used to implement the styled-jsx
transform.
The new Rust compiler is backwards compatible. If you have an existing Babel configuration, you will automatically be opted out. We have plans to port parsing for popular libraries like styled-components
, emotion
, and relay
soon. If you\'re using a custom Babel setup, please share your configuration.
You can also opt-in to using the Rust compiler for minification. This is 7x faster than Terser. Minification is opt-in until it’s thoroughly validated as it replaces multi-year infrastructure.
\\nmodule.exports = {\\n swcMinify: true,\\n};
On top of hiring DongYoon Kang, the creator of SWC, and Maia Teegarden, a contributor to Parcel, we are continuing to invest in the Rust ecosystem. If you have experience working with Rust, please apply to join our team.
\\nFor more information, watch our demo from Next.js Conf.
\\nMiddleware enables you to use code over configuration. This gives you full flexibility in Next.js because you can run code before a request is completed. Based on the user\'s incoming request, you can modify the response by rewriting, redirecting, adding headers, or even streaming HTML.
\\nMiddleware can be used for anything that shares logic for a set of pages, including:
\\nMiddleware uses a strict runtime that supports standard Web APIs like fetch
. This works out of the box using next start
, as well as on Edge platforms like Vercel, which use Edge Middleware.
To use Middleware in Next.js, you can create a file pages/_middleware.js
. In this example, we use the standard Web API Response (MDN):
export function middleware(req, ev) {\\n return new Response(\'Hello, world!\');\\n}
For more information, watch our demo from Next.js Conf and check out the documentation.
\\nReact 18 will add features like Suspense, automatic batching of updates, APIs like startTransition
, and a new streaming API for server rendering with support for React.lazy
.
We\'ve been working closely with the React team at Facebook to prepare Next.js for React 18 as it moves towards a stable release. We\'re making these features available to try today in Next.js 12 under an experimental flag.
\\nnpm install react@alpha react-dom@alpha
Concurrent features in React 18 include built-in support for server-side Suspense and SSR streaming support. This allows you to server-render pages using HTTP streaming. This is an experimental feature in Next.js 12, but once enabled, SSR will use the same strict runtime as Middleware.
\\nTo enable, use the experimental flag concurrentFeatures: true
:
module.exports = {\\n experimental: {\\n concurrentFeatures: true,\\n },\\n};
React Server Components allow us to render everything, including the components themselves, on the server. This is fundamentally different from server-side rendering where you\'re pre-generating HTML on the server. With Server Components, there\'s zero client-side JavaScript needed, making page rendering faster. This improves the user experience of your application, pairing the best parts of server-rendering with client-side interactivity.
\\nmodule.exports = {\\n experimental: {\\n concurrentFeatures: true,\\n serverComponents: true,\\n },\\n};
Next.js now enables you to do data fetching at the component level, all expressed as JSX. By using React Server components, we can simplify things. Special functions like getServerSideProps
or getStaticProps
are no longer needed. This aligns with the React Hooks model of colocating data fetching with your components.
You can rename any Next.js page to .server.js
to create a Server Component and import client components directly inside your Server Components. These client components will hydrate and become interactive, so you add functionality like upvotes.
We\'re currently working on server-side Suspense, selective hydration, and streaming rendering in Next.js and will share our progress in a future blog post.
\\nSpecial thanks to our collaborators Kara Erickson and Gerald Monaco on the Google Aurora team for their work on React 18 and Server Components.
\\nFor more information, watch our demo from Next.js Conf and check out the documentation.
\\nES modules bring an official, standardized module system to JavaScript. They\'re supported by all major browsers as well as Node.js.
\\nThis standard pushes the web ecosystem forward by enabling smaller package sizes and JavaScript bundles, ultimately leading to a better user experience. As the JavaScript ecosystem transitions from Common JS (the old standard) to ES modules, we\'re committed to helping developers incrementally adopt these improvements without unnecessary breaking changes.
\\nStarting with Next.js 11.1, we added experimental support for ES modules being prioritized over CommonJS modules. In Next.js 12, this is now the default. Importing NPM modules that only provide CommonJS is still supported.
\\nNext.js 12 includes experimental support for importing ES Modules through URLs, no install or separate build step is required.
\\nURL imports allow you to use any package directly through a URL. This enables Next.js to process remote HTTP(S) resources exactly like local dependencies.
\\nIf a URL import is detected, Next.js will generate a next.lock
file to track remote resources. URL imports are cached locally to ensure you can still work offline. Next.js supports both client and server URL imports.
To opt-in, add the allowed URL prefixes inside next.config.js
:
module.exports = {\\n experimental: {\\n urlImports: [\'https://cdn.skypack.dev\'],\\n },\\n};
Then, you can import modules directly from URLs:
\\nimport confetti from \'https://cdn.skypack.dev/canvas-confetti\';
Any CDN that serves ES modules will work, including no-code and design tools like Framer:
\\n\\nFor more information, watch our demo from Next.js Conf and check out the documentation.
\\nCurrently, Incremental Static Regeneration with fallback: true
renders a fallback state before rendering the page contents on the first request to a page that was not generated yet. To block the page from loading (server-rendering), you would need to use fallback: \'blocking\'
.
In Next.js 12, web crawlers (e.g. search bots) will automatically server-render ISR pages using fallback: true
, while still serving the previous behavior of the fallback state to non-crawler User-Agents. This prevents crawlers from indexing loading states.
The built-in Image Optimization API now supports AVIF images, enabling 20% smaller images compared to WebP.
\\nAVIF images can take longer to optimize compared to WebP, so we\'re making this feature opt-in using the new images.formats
property in next.config.js
:
module.exports = {\\n images: {\\n formats: [\'image/avif\', \'image/webp\'],\\n },\\n};
This list of formats is used to determine the optimized image format on-demand using the request\'s Accept
header. Since AVIF is first, it will be served if the browser supports AVIF. If not, WebP will be served if the browser supports WebP. If neither format is supported, the original image format will be served.
In Next.js 8, we introduced the target
option. This allowed for outputting Next.js pages as standalone JavaScript bundles by bundling all dependencies using webpack during the build. We quickly realized this wasn\'t ideal and instead created @vercel/nft
. @vercel/nft
has been used for over 2 years on all deployments on the Vercel platform.
Now, we\'re bringing these improvements directly into the Next.js framework by default, for all deployment platforms, providing a significantly improved approach over the target
option.
Next.js 12 automatically traces which files are needed by each page and API route using @vercel/nft
, and outputs these trace results next to the next build
output, allowing integrators to leverage the traces Next.js provides automatically.
These changes also optimize applications deploying using tools like Docker through next start
. By leveraging @vercel/nft
, we will be able to make the Next.js output standalone in the future. No dependencies will be required to be installed to run the application, massively reducing the Docker image size.
Bringing @vercel/nft
into Next.js supersedes the target
approach, making target
deprecated in Next.js 12. Check out the documentation for more info.
pages/_app.js
or pages/_document.js
to your application now automatically replaces the built-in version without requiring a reboot of the Next.js CLI.next lint
with the --file
flag.tsconfig.json
path.next.config.mjs
is now supported for writing the configuration as ES modules.target
in next.config.js
is no longer needed.next/image
now uses a span
as the wrapping element instead of a div
.12.0.0
to 12.22.0
, which is the first version of Node.js with native ES modules support.To learn more, check out the upgrade guide.
\\nFive years ago, we released Next.js to the public. We set out to build a zero-configuration React framework that simplifies your developer experience. Looking back, it\'s incredible to see how the community has grown, and what we\'ve been able to ship together. Let\'s keep going.
\\nNext.js is the result of the combined work of over 1,800 individual developers, industry partners like Google and Facebook, and our core team.
\\nThis release was brought to you by the contributions of: @ka2n, @housseindjirdeh, @rojserbest, @lobsterkatie, @thibautsabot, @javivelasco, @sokra, @rishabhpoddar, @kdy1, @huozhi, @georgegach, @ionut-botizan, @paul-creates, @TimBarley, @kimizuy, @devknoll, @matamatanot, @christianvuerings, @pgrodrigues, @mohamedbhy, @AlfonzAlfonz, @kara, @molebox, @angelopoole, @oste, @genetschneider, @jantimon, @kyliau, @mxschmitt, @PhattOZ, @finn-orsini, @kriswuollett, @harryheman, @GustavoEdinger, @AryanBeezadhur, @Blevs, @colevscode, @atcastle, @ijjk, @velocity23, @jonowu, @timneutkens, @whitep4nth3r, @micro-chipset, @TyMick, @padmaia, @arthurdenner, @vitorbal, @zNeb, @jacksonhardaker, @shuding, @kylemh, @Bundy-Mundi, @ctjlewis, @thien-do, @leerob, @Dev-CasperTheGhost, @janicklas-ralph, @rezathematic, @KonstHardy, @fracture91, @lorensr, @Sheraff, @HaNdTriX, @emilio, @oluan, @ddzieduch, @colinclerk, @x4th, @volcareso, @oiva, @sinchang, @scottrepreneur, @smakosh, @catnose99, @adrienharnay, @donsn, @andersonleite, @msp5382, @tim-hanssen, @appsplash99, @alexvilchis, @RobEasthope, @royal, @Perry-Olsson, @well-balanced, @mrmckeb, @buraksakalli, @espipj, @prateekbh, @AleksaC, @eungyeole, and @rgabs
","description":"As we announced at Next.js Conf, Next.js 12 is our biggest release ever: Rust Compiler: ~3x faster Fast Refresh and ~5x faster builds\\nMiddleware (beta): Enabling full flexibility in Next.js with code over configuration\\nReact 18 Support: Native Next.js APIs are now supported, as…","guid":"https://nextjs.org/blog/next-12","author":null,"authorUrl":null,"authorAvatar":null,"publishedAt":"2021-10-25T16:00:00.780Z","media":[{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Fnext-12%2Fswc.png&w=3840&q=75","type":"photo","width":1314,"height":445.5},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Fnext-12%2Fswc.png&w=3840&q=75","type":"photo","width":1314,"height":445.5},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Fnext-12%2Fmiddleware.png&w=1200&q=75","type":"photo","width":600,"height":337.5},{"url":"https://nextjs.org/_next/image?url=%2Fstatic%2Fblog%2Fnext-12%2Fmiddleware.png&w=1200&q=75","type":"photo","width":600,"height":337.5}],"categories":null,"attachments":null,"extra":null,"language":null},{"title":"Next.js 11","url":"https://nextjs.org/blog/next-11","content":"As we announced at Next.js Conf, our mission to create the best developer experience continues with Next.js 11, featuring:
\\nnext/script
: Automatically prioritize loading of third-party scripts to improve performance.next/image
: Reduce layout shift and create a smoother visual experience with automatic size detection and support for blur-up placeholders.Update today by running npm i next@latest react@latest react-dom@latest
and reference the migration guide below.
Even with great tools and automatic optimizations in frameworks, site owners and app developers are often asked to become experts in UX quality topics, like performance, security, and accessibility. As features are added and teams scale, developers need to think differently.
\\nThrough their work building large-scale web applications like Search and Maps, Google has proven that frameworks can play a crucial role in maintaining quality as teams and applications scale. By leveraging a system of strong defaults and safeguards, they empower developers to focus more on features and products.
\\nToday, Google\'s Web Platforms team has begun open-sourcing their system with Conformance for Next.js.
\\nConformance is a system that provides carefully crafted solutions and rules to support optimal loading and Core Web Vitals, with further additions coming to support other quality aspects like security and accessibility. These solutions free your team from memorizing all the latest rules for optimal loading performance, while still giving you the flexibility to make the right choices for your applications.
\\nAlong with many foundational optimizations backed by performance research, Next.js 11 now supports ESLint out of the box to make it easier to catch framework-specific issues during development and set guidelines for your team to ensure best practices even as you scale.
\\nTo get started with ESLint, run npx next lint
after upgrading to Next.js 11. The ESLint integration works for new and existing Next.js applications, providing a new set of rules to help developers build better applications.
$ npx next lint\\nWe created the .eslintrc file for you and included the base Next.js ESLint configuration.\\n\\n./pages/about.js\\n7:9 Warning: Do not include stylesheets manually. See: https://nextjs.org/docs/messages/no-css-tags. @next/next/no-css-tags\\n10:7 Warning: External synchronous scripts are forbidden. See: https://nextjs.org/docs/messages/no-sync-scripts. @next/next/no-sync-scripts\\n\\n./pages/index.js\\n4:10 Warning: Do not use the HTML <a> tag to navigate to /about/. Use Link from \'next/link\' instead. See: https://nextjs.org/docs/messages/no-html-link-for-pages. @next/next/no-html-link-for-pages\\n\\nNeed to disable some ESLint rules? Learn more here: https://nextjs.org/docs/pages/building-your-application/configuring/eslint#disabling-rules\\n\\n✨ Done in 1.94s.\\n
Learn more about Conformance for frameworks on Google\'s blog.
\\nSince Next.js 10, we\'ve been obsessed with further improving the developer experience of Next.js. In 10.1 and 10.2 we improved startup time by up to 24% and shaved off another 40% of processing time for changes through React Fast Refresh. You\'ve been getting these amazing speed improvements just by keeping Next.js updated.
\\nNext.js 11 includes another optimization to Babel to further reduce the startup time. We\'ve created a brand new implementation of the Babel loader for webpack, optimizing loading and adding an in-memory config caching layer. In practice, this means no change for developers but will ultimately mean a faster development experience.
\\nThe new Next.js Script Component is a foundational optimization that enables developers to set the loading priority of third-party scripts to save developer time and improve loading performance.
\\nWebsites often need third parties for things like analytics, ads, customer support widgets, and consent management. However, these scripts tend to be heavy on loading performance and can drag down the user experience. Developers often struggle to decide where to place them in an application for optimal loading.
\\nWith next/script
, you can define the strategy
property and Next.js will automatically prioritize them to improve loading performance:
beforeInteractive
: For critical scripts that need to be fetched and executed before the page is interactive, such as bot detection and consent management. These scripts are injected into the initial HTML from the server and run before self-bundled JavaScript is executed.afterInteractive
(default): For scripts that can fetch and execute after the page is interactive, such as tag managers and analytics. These scripts are injected on the client-side and will run after hydration.lazyOnload
For scripts that can wait to load during idle time, such as chat support and social media widgets.<Script\\n src={url}\\n strategy=\\"beforeInteractive\\" // lazyOnload, afterInteractive\\n/>
You can also run code after loading. For example, you can wait to execute code until after a user has answered consent:
\\n<Script\\n src={url} // consent mangagement\\n strategy=\\"beforeInteractive\\"\\n onLoad={() => {\\n // If loaded successfully, then you can load other scripts in sequence\\n }}\\n/>
We\'ve also changed the default script loading experience in Next.js 11 from preloading and async
to defer
. Third-party scripts often compete with higher priority resources, such as CSS, fonts, and images. Maintaining the proper sequencing relative to these resources, as well as other scripts, is an undue burden on developers.
By providing a Script Component with a default loading strategy of afterInteractive
, developers now have better defaults for optimal performance, with the ability to still choose beforeInteractive
as needed.
To learn more about the technical choices behind switching the default, check out the RFC and challenges with preload from the Google Chrome team.
\\nWe\'re excited to share two of our community\'s top requested features for the next/image
component, reducing Cumulative Layout Shift and creating a smoother visual experience.
Use the import
keyword for the image src
to automatically define width
and height
for static images.
For example, using the built-in Image component is now even easier:
\\nimport Image from \'next/image\';\\nimport author from \'../public/me.png\';\\n \\nexport default function Home() {\\n return (\\n // When importing the image as the source, you\\n // don\'t need to define `width` and `height`.\\n <Image src={author} alt=\\"Picture of the author\\" />\\n );\\n}
next/image
now supports blur-up placeholders to ease the transition from blank space to image and reduce perceived loading time, particularly for users with slower internet connections.
To use blurred placeholders, add placeholder=\\"blur\\"
to your image.
<Image src={author} alt=\\"Picture of the author\\" placeholder=\\"blur\\" />
Next.js also supports blurring dynamic images by allowing you to provide a custom blurDataURL
, which is provided by your backend. For example, you can generate a blurha.sh on the server.
<Image\\n src=\\"https://nextjs.org/static/images/learn.png\\"\\n blurDataURL=\\"data:image/jpeg;base64,/9j/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj/2wBDAQcHBwoIChMKChMoGhYaKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCj/wAARCAAIAAoDASIAAhEBAxEB/8QAFQABAQAAAAAAAAAAAAAAAAAAAAb/xAAhEAACAQMDBQAAAAAAAAAAAAABAgMABAUGIWEREiMxUf/EABUBAQEAAAAAAAAAAAAAAAAAAAMF/8QAGhEAAgIDAAAAAAAAAAAAAAAAAAECEgMRkf/aAAwDAQACEQMRAD8AltJagyeH0AthI5xdrLcNM91BF5pX2HaH9bcfaSXWGaRmknyJckliyjqTzSlT54b6bk+h0R//2Q==\\"\\n alt=\\"Picture of the author\\"\\n placeholder=\\"blur\\"\\n/>
With Next.js 10.2, we expanded the rollout of webpack 5 to all applications without a custom webpack configuration in their next.config.js
. Today, we\'re making webpack 5 the default for all Next.js applications, which will provide a variety of features and improvements.
We\'ve worked closely with the community to ensure a smooth transition to webpack 5, over 3,400 existing Next.js integration tests run on every pull request with webpack 5 enabled.
\\nIf your application has a custom webpack configuration, we recommend following the upgrade documentation for webpack 5. If you run into any issues, please share feedback with us.
\\nOver the past six months, we\'ve seen an increase in applications migrating from Create React App to Next.js to leverage many of the developer experience and end-user performance improvements Next.js provides.
\\nTo help developers convert their applications to Next.js, we\'ve introduced a new tool to @next/codemod
that automatically converts Create React App applications to be Next.js compatible.
The transform automatically adds a pages/
directory and moves CSS imports to the right location. It\'ll also enable a Create React App compatibility mode in Next.js that ensures some patterns used in Create React App work with Next.js.
By leveraging the new transform, you can incrementally adopt Next.js while maintaining the functionality of the existing Create React App application.
\\nTo get started migrating your Create React App project use the following command:
\\nnpx @next/codemod cra-to-next
This feature is currently experimental, please share any feedback in this discussion.
\\nNext.js Live is a continuation of our mission to make development not only faster and more enjoyable, but crucially more inclusive of the entire organization. By leveraging cutting-edge technology like ServiceWorker, WebAssembly, and ES Modules, Next.js Live puts the entire development process in the web browser. This opens up possibilities like collaborating and sharing instantaneously with a URL, without a build step. For developers, this means a faster feedback loop, less time waiting for builds, and real-time peer programming and editing within the browser.
\\nTo learn more about Next.js Live and how you can pair it with Vercel\'s real-time collaboration engine, see the Next.js Live section of the documentation.
\\nNext.js 11 introduces a few breaking changes which should not affect the majority of users. These legacy features have been maintained in a backward-compatible way for years, some as far back as v4.0
.
These features were removed to decrease the bundle size and ensure the codebase is maintainable for the future. To learn more about upgrading from version 10 to 11, please see the upgrade guide.
\\nWith Next.js 11, the minimum React version has been updated to 17.0.2
. Please see the React 17 blog post for more details. We are also working closely with the React team as they introduce React 18. Next.js 11 uses createRoot
when React 18 alpha is being used.
Next.js is the result of the combined work of over 1,600 individual developers, industry partners like Google and Facebook, and our core team.
\\nWe\'re proud to see that community continue to grow. Within the last six months alone, we\'ve seen a 50% increase in Next.js downloads on NPM, from 4.1M to 6.2M and the number of homepages using Next.js in the Alexa top 10,000 has grown 50%.
\\nThis release was brought to you by the contributions of: @kahy9, @ljosberinn, @leerob, @kettanaito, @thomasboyt, @hussainanjar, @styfle, @devknoll, @LiuuY, @timneutkens, @housseindjirdeh, @PepijnSenders, @janicklas-ralph, @payapula, @tmtk75, @ijjk, @hiramhuang, @daku10, @atcastle, @matamatanot, @pelhage, @Lukazovic, @Mzaien, @gleich, @geshan, @Munawwar, @ykzts, @vitalybaev, @mottox2, @vvo, @chrisneven, @turneand, @d3lm, @akellbl4, @sokra, @johnjago, @alicanyildirim, @sanathusk, @valse, @samrobbins85, @SamVerschueren, @ademilter, @ctjlewis, @brandondc741, @eltociear, @martpie, @kasipavankumar, @joecohens, @alexbrazier, @jamsinclair, @fabianishere, @rokinsky, @msidqi, @rubensdemelo, @Simply007, @bradlc, @SinimaWath, @rgabs, @darshkpatel, @sumanthratna, @shuding, @prophet1996, @Joonpark13, @tremby, @stefanprobst, @dopt, @rishabhpoddar, @aydinkn, @ErfanMirzapour, @tubbo, @frontendtony, @eric-burel, @iker-barriocanal, @eps1lon, @Gigiz, @mplis, @HaNdTriX, and @jigsawye.
\\nThe following features were mentioned in Next.js Conf, but were shipped early through versions 10.1 and 10.2:
\\nnext/image
Improvements: Apple Silicon (M1) Support, plus more layout and loader options.We are excited to introduce Next.js 10.2, featuring:
\\nnext dev
.Update today by running npm i next@latest
.
With Next.js 10.1, we improved Fast Refresh and decreased installation times. We\'re excited to share additional performance improvements enabled through webpack 5.
\\nToday, we\'re expanding the rollout of webpack 5 to Next.js applications. Starting from Next.js 10.2, all applications that do not use a custom webpack configuration in their next.config.js
will automatically use webpack 5.
When webpack 5 is enabled, you\'ll automatically get new features and improvements like:
\\nnext build
runs. Only changed files will be recompiled, leading to increased performance. Vercel customer Scale observed a 63% speedup on subsequent builds.next build
runs is now deterministic, improving browser caching of JavaScript assets in production. Hashes are kept the same when the content of a page does not change.export *
tracks more information and no longer flags the default export as used. Inner-module tree-shaking is also enabled, allowing for imports that are only used in an unused export to be tree shaken.We\'ve worked hard to ensure a smooth transition from webpack 4 to 5. The Next.js core test suite with over 3,400 integration tests runs on every pull request with webpack 5 support enabled.
\\nIf your application has a custom webpack configuration, we recommend following the documentation to enable webpack 5. After upgrading to webpack 5 in Next.js, please share any feedback with us.
\\nWe\'ve improved the Next.js CLI initialization making boot time for next dev
up to 24% faster after the first run. For example, next dev
for vercel.com went from 3.3s to 2.5s.
We\'re on a mission to make your local development experience real-time (20x faster). Stay tuned for additional startup performance improvements in upcoming releases.
\\nRoute changes are now announced to screen readers and other assistive technology by default.
\\nThe example below shows the heading \\"Real Data. Real Performance\\" being announced by macOS VoiceOver on client-side navigation. The page name is found by first looking for an <h1>
element, falling back to document.title
, and lastly to the pathname.
Thank you to Kyle Boss and Kitty Giraudel for helping land this feature.
\\nNext.js rewrites, redirects, and headers now support a new has
property allowing you to match against incoming headers, cookies, and query strings.
Vercel customer Joyn uses has
to optimize content for both discoverability and performance. For example, you could redirect old browsers based on the User-Agent:
module.exports = {\\n async redirects() {\\n return [\\n {\\n source: \'/:path((?!old-browser$).*)\',\\n has: [\\n {\\n type: \'header\',\\n key: \'User-Agent\',\\n value:\\n \'Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; Trident/6.0; IEMobile/10.0; ARM; Touch; Microsoft; Lumia 950)\',\\n },\\n ],\\n destination: \'/old-browser\',\\n permanent: false,\\n },\\n ];\\n },\\n};
Another example could be redirecting users based on their location:
\\nmodule.exports = {\\n async redirects() {\\n return [\\n {\\n source: \'/:path((?!uk/).*)\',\\n has: [\\n {\\n type: \'header\',\\n key: \'x-vercel-ip-country\',\\n value: \'GB\',\\n },\\n ],\\n destination: \'/uk/:path*\',\\n permanent: true,\\n },\\n ];\\n },\\n};
Finally, you could redirect if a user is already logged in:
\\nmodule.exports = {\\n async redirects() {\\n return [\\n {\\n source: \'/\',\\n has: [\\n {\\n type: \'header\',\\n key: \'x-authorized\',\\n value: \'(?<authorized>yes|true)\',\\n },\\n ],\\n destination: \'/dashboard?authorized=:authorized\',\\n permanent: false,\\n },\\n ];\\n },\\n};
To learn more and explore additional examples, check out the redirects documentation.
\\n82% of web pages for desktop use web fonts. Custom fonts are important for the branding, design, and cross-browser/device consistency of your site. However, using a web font should not come at the cost of performance.
\\nNext.js now supports Automatic Webfont Optimization when using web fonts. By default, Next.js will automatically inline font CSS at build time, eliminating an extra round trip to fetch font declarations. This results in improvements to First Contentful Paint (FCP) and Largest Contentful Paint (LCP). For example:
\\n// Before\\n<link href=\\"https://fonts.googleapis.com/css2?family=Inter\\" rel=\\"stylesheet\\" />\\n \\n// After\\n<style data-href=\\"https://fonts.googleapis.com/css2?family=Inter\\">\\n @font-face {\\n font-family: \'Inter\';\\n font-style: normal;\\n <!-- ... -->\\n }\\n</style>
Automatic Webfont Optimization currently supports Google Fonts and we\'re working to expand support further to other font providers. We\'re also planning to add control over loading strategies and font-display
values. By optimizing fonts by default, we\'re able to help developers ship faster websites and improve their Core Web Vitals without any additional effort.
Thank you our partners at Google and Janicklas Ralph for helping land this feature.
\\nWe\'re excited to announce Tobias Koppers, the author of webpack, has joined the Next.js team at Vercel.
\\nWe are thankful to our community, including all the external feedback and contributions that helped shape this release.
\\nThis release was brought to you by the contributions of: @rpxs, @lemarier, @RayhanADev, @janicklas-ralph, @devknoll, @felipeptcho, @rishabhpoddar, @sokra, @m-leon, @turadg, @PierreBerger, @divmain, @dominikwilkowski, @pranavp10, @ijjk, @santidalmasso, @HaNdTriX, @jamesgeorge007, @garmeeh, @leerob, @shuding, @feute, @timneutkens, @alexvilchis, @Timer, @malixsys, @sahilrajput03, @marcvangend, @steven-tey, @julienben, @umarsenpai, @Mzaien, @merceyz, @AntelaBrais, @SystemDisc, @M1ck0, @jbmoelker, @jaisharx, @amannn, @vkarpov15, @gaelhameon, @4ortytwo, @Simply007, @styxlab, @xCloudzx, @wodCZ, @emmanuelgautier, @leosuncin, @ludder, @geritol, @vassbence, @vvo, @portenez, @arshad, @tarunama, @flybayer, @Hanaffi, @SokratisVidros, @chibicode, @kylemarshall18, and @jarrodwatts.
","description":"We are excited to introduce Next.js 10.2, featuring: Faster Builds: Up to ~60% faster subsequent builds with caching.\\nFaster Refresh: 100ms to 200ms faster refresh.\\nFaster Startup: Up to ~24% faster next dev.\\nImproved Accessibility: Route changes are now announced by screen…","guid":"https://nextjs.org/blog/next-10-2","author":null,"authorUrl":null,"authorAvatar":null,"publishedAt":"2021-04-27T16:00:00.642Z","media":[{"url":"https://nextjs.org/static/blog/next-10-2/a11y.mp4","type":"video","width":926.6666666666666,"height":718.6666666666666}],"categories":null,"attachments":null,"extra":null,"language":null}],"readCount":1243,"subscriptionCount":15,"analytics":{"feedId":"57802109569674240","updatesPerWeek":0,"subscriptionCount":15,"latestEntryPublishedAt":null,"view":0}}')