Vercel recently announced Next Js 13 (stable) at Next Js Conf, and it comes with some great and useful features which made Next Js even faster and more efficient in Development and Production.
Overall developer experience has been very smooth with the addition of new features like
app
Directory (beta)- TurboPack ( alpha )
- New
next/image
- Improved
next/link
- New @next/fonts ( beta )
Well, discuss each new feature in a separate post meanwhile let me introduce them in brief.
You can read about them on Next Js official blog
#app Directory ( beta )
Next Js added a new file structure, now instead of using the pages directory as our main directory, we can also use the app directory which comes with new features and a routing system.
In regular pages structure, we used to organize our projects like the one below.
ProjectName
-pages
šblog
index.js
[slug].js
_app.js
index.js
-public
-src
-styles
-package.json
Now we can use app directory for our main pages like below
ProjectName
-app
šblog
page.js
[slug].js
layout.js
layout.js
page.js
-public
-src
-styles
-package.json
the new app directory requires page.js instead of index.js, the app directory, and each subdirectory should contain a page.js, and we may create layout.js for layouts, error for errors when components fail to load in each directory but are optional.
This is a new feature and is still in the beta version, so it is not recommended to use in production yet.
#TurboPack ( alpha )
Next Js is replacing Webpack with the Rust-based bundling and build toolTurboPack for better and faster build and reload. It is still in the alpha version.
#@next/fonts
Next Js 13 introduces a new fonts library which will automatically host all the necessary fonts locally inside the project so we donāt have to import from remote CDN while staying in our project which prevents layout shifts when page load delays.
#New next/link
Now we don have to use an extra <a>
tag inside <Link>
components as new next/link will automatically add an <a>
inside to the page which is absolutely awesome.
#New next/image
With improved next/image, now we donāt have to give the height and width for local images, Next Js will automatically set width and height according to the width and height of the image,
Note: this only works for local images if youāre importing images from the remote server you still have to provide width and height in numeric value.
New next/image comes with the native lazy loading support which boosts the performance and load time.
#Upgrading existing projects to Next Js 13
We can incrementally upgrade our existing Next Js 12 or any older Next Js project to Next Js 13, which means we can still use new features of Next Js 13 in our project which are ready for the production environment.
Which are
- next/image
- next/link
So in this guide, weāll see how can we upgrade to Next Js 13 and update our old code base easy to use new components with the help of codemod.
To update your Next js project to Next Js 13 use one of the following commands according to your environment
npm i next@latest react@latest react-dom@latest eslint-config-next@latest
# or
yarn add next@latest react@latest react-dom@latest eslint-config-next@latest
# or
pnpm up next react react-dom eslint-config-next --latest
after running the above command check your package.json for the latest Next Js version
Now weāll use codemod to incrementally update our codebase for new components and add legacy support if we wish to use older libraries along with the new ones.
#@next/codemod
Next.js provides Codemod transformations to help upgrade your Next.js codebase when a feature is deprecated.
Codemods are transformations that run on your codebase programmatically. This allows for a large number of changes to be applied without having to manually go through every file.
Read more about codemod on the official documentation.
Install codemod in your project if you havenāt already by using the following command
npm install @next/codemod@latest
#next/link
<Link>
components earlier needed and <a>
tag as a child to work properly but in Next Js 13 it is no more necessary as next js automatically added a <a>
tag in our page so we donāt need to pass <a>
tag as a child in <Link>
components anymore.
Below is the comparison between the old and new link component
import Link from 'next/link'
// Next.js 12: `<a>` has to be nested otherwise it's excluded
<Link href="/about">
<a className="nav-links">Home</a>
</Link>
// Next.js 13: `<Link>` always renders `<a>` under the hood with all the props
<Link href="/about" className="nav-links">
About
</Link
to update all your existing <Link>
components to new style <Link>
tag run the following codemod
npx @next/codemod new-link /pages
// new-link is the codemod defined by next js team
// ./pages is the path where codemod will be executed
npx @next/codemod@latest <transform> <path> // use this syntax
you can use
--dry
to do a dry run, no code will change.
--print
to see the changes that happened
Example
npx @next/codemod new-link /pages --dry //will show the pages eligible for change
npx @next/codemod new-link /pages //will change all old <Link> tag to new one
npx @next/codemod new-link /pages --print //will show what changes happened
after running the new-link
codemod all your old style <Link>
components will update with the new style and all the attributes and props of <a>
tag will be assigned to <Link>
tag.
import Link from 'next/link'
//OLD
<Link href="/about">
<a className="nav-links">Home</a>
</Link>
//NEW
<Link href="/about" className="nav-links">
About
</Link
#next/image
As soon as we updated our project to Next Js 13 the new next/image library was installed so now we have to follow the style of the new next/image and the old next/image is renamed to next/legacy/image
so if we want to see the old image library we have to add support legacy library and we can do this in seconds with the help of codemod given below
//changes all next/image import to next/legacy/image in all files inside ./pages directory
//if you want to do this in another directory the chage ./pages => newPathname
npx @next/codemod@latest next-image-to-legacy-image ./pages
after running above codemod
below code
import Image1 from 'next/image';
import Image2 from 'next/future/image';
export default function Home() {
return (
<div>
<Image1 src="/test.jpg" width="200" height="300" />
<Image2 src="/test.png" width="500" height="400" />
</div>
);
}
will change to
// 'next/image' becomes 'next/legacy/image'
import Image1 from 'next/legacy/image';
// 'next/future/image' becomes 'next/image'
import Image2 from 'next/image';
export default function Home() {
return (
<div>
<Image1 src="/test.jpg" width="200" height="300" />
<Image2 src="/test.png" width="500" height="400" />
</div>
);
}
now you can use old as well as new next/image and gain great performance while maintaining old style of your webpage.
I hope you find this guide helpful, Happy coding š