Vercel recently announced the long-awaited upgrade for the Next.js framework: Next.js 13! In software terms, it is a significant upgrade. It introduced numerous highly anticipated features. However, it's common to wait until the release from beta to ensure it's production-ready before upgrading the entire codebase. It was announced to be production-ready at the end of 2023.
We recently decided to upgrade our home site to leverage its out-of-the-box features and further improve performance. If you've been hesitant about upgrading your Next.js application, look no further. I've compiled a comprehensive yet simple guide.
While there were a lot of features added with Next.js 13, I want to give you the quickest rundown of what is needed from a base level. Some components were upgraded that are likely used in every Next.js application. There are ways to work around these changes or handle the upgrades yourself.
<Image />
ComponentNext.js 12 introduced a temporary import called /next/future/image
that contained some new improvements like less client-side js, updated processes to extend styles, and native browser lazy loading. Next.js 13 incorporates these features as standard with next/image
. This does require some updating and refactoring if you want to re-style your images.
If you prefer to upgrade later without updating your existing <Image />
components, you can avoid this by running a simple codemod:
npx @next/codemod@latest next-image-to-legacy-image ./pages
This command will safely rename any imports from next/image
to next/legacy/image
in Next.js 10, 11, or 12 versions, as shown below:
// old import import MyImage from 'next/image' // new import import MyImage from 'next/legacy/image'
<Link />
ComponentIn older versions of Next.js, a child <a>
tag was required for a <Link>
component. (There was an experimental option in version 12.2). Next.js 13 no longer requires the <a>
tag within <Link>
components by default, as <Link>
now renders the <a>
tag automatically.. This cleans up your code base quite a bit. Next.js provides a codemod to simplify this conversion:
npx @next/codemod@latest new-link ./pages
This command will safely remove any <a>
tags inside of existing <Link>
components in Next.js 10, 11, or 12 versions like so:
// old method <Link href="/contact"> <a>Contact</a> </Link> // new method <Link href="/contact"> Contact </Link>
Note: Some items may not be auto-fixed successfully. In such cases, the component will contain a legacyBehavior
prop and function as before. You can also manually remove the tag if desired.
app
DirectoryThis is a significant upgrade, and I recommend reading more about it here. This is intended to be a page by page migration, but requires a decent lift since all of your pages and structure will have to be modified. It is still in beta, so for now, it is set through an optional flag.
Next.js 13 introduces built-in SEO support, allowing metadata definition inside individual components for improved SEO. A few examples from the Next.js documentation:
Static Meta Data
import type { Metadata } from 'next' export const metadata: Metadata = { title: 'Products', description: 'A comprehensive list of products we offer.', } export default function MyPage() { return '...' }
Dynamic Meta Data
import type { Metadata } from 'next' async function getProduct(id) { const res = await fetch(`https://.../api/products/${id}`) return res.json() } export async function generateMetadata({ params }): Promise<Metadata> { const product = await getProduct(params.id) return { title: product.title } } export default async function Page({ params }) { const product = await getProduct(params.id) // ... }
<Script />
componentIf you are using the new beta app folder structure, beforeInteractive
scripts have been relocated from _document.js
to app/layout.tsx
.
Next.js 13 introduces a new font module next/font
that enables customization of the font loading process while maintaining speed and privacy. It is not required for the upgrade.
To upgrade to Next.js 13, you need to update the following dependencies to their minimum versions:
React
yarn add react@18.2.0
or npm upgrade react@18.2.0
React-DOM
yarn add react-dom@18.2.0
or npm upgrade react-dom@18.2.0
Node
npm i -g node@16.8
Keeping your application up to date is essential. Upgrading ensures compatibility with the latest packages, avoiding potential issues caused by deprecated or outdated dependencies. Regular updates provide peace of mind and keep your app running smoothly, similar to updating firmware or operating systems on devices.
Software moves quickly. While we are busy building products, teams are constantly improving the tools we use to build and maintain these products. This rapid pace of development in the software industry means that new versions and updates are released frequently. Upgrading to newer versions is often necessary, as it can prevent us from encountering issues with deprecated or incompatible dependencies. By staying up to date with package upgrades, we can avoid potential difficulties and ensure the smooth functioning of our applications.
Thanks for reading!