Unless you've been hiding under a rock you'll know that when it comes to creating your next React project CreateReactApp isn't what you want to be using for your base. NextJS is definitely the front runner of the React Frameworks, and it's just had a major update in the form of v13.
Routing
The first thing that stuck out was the change in the folder layout. Everything now runs from the /app
folder. This is
functionality that is still in beta and can be rolled back, but looking at the file tree below we can see that
the /app
folder has all our pages and styles in whilst the /pages
folder still has the /api
folder for all the
endpoint files. I'm thinking that this will move to an /api
folder in the root alongside /app
in future.
├── app
│ ├── globals.css
│ ├── head.tsx
│ ├── layout.tsx
│ ├── page.module.css
│ └── page.tsx
├── pages
│ └── api
│ └── hello.ts
├── next-env.d.ts
├── next.config.js
├── node_modules
├── package.json
├── pnpm-lock.yaml
├── public
│ ├── favicon.ico
│ ├── next.svg
│ ├── thirteen.svg
│ └── vercel.svg
├── README.md
└── tsconfig.json
You'll also notice the absence of the index.tsx
file. Now the page.tsx
serves as the root file for the folder so
anything calling for the root will be served with page.tsx
. There is also now the page.module.css
instead
of home.module.css
and I guess that's to suit the naming of the file that have changed?
Now when we want to have /products/
we have to have a folder called products with a page.tsx
in it. Routes are now
folder based instead of the previous file and folder solution in NextJS 12.
Turbopack
For quite a long time we've been using Webpack to bundle or code up. Now Webpack creator Tobias Koppers has joined Vercel (the makers of NextJS) and brought along the successor to Webpack called Turbopack.
Turbopack's main selling point is that it is significantly faster that Webpack. It does this by monitoring the state of the framework and only running changes. It's also faster due to it being written in Rust.
To switch to Turbopack in NextJS add the --turbo
flag to your scripts config in packages.json
"scripts": {
"dev": "next dev --turbo",
"build": "next build",
"start": "next start",
"lint": "next lint"
}
Future plans are for everything NextJS to be run with Turbopack instead of Webpack. How this new tool will benefit NextJS users is yet to be felt in its infancy, but the bigger the app the greater the difference according to the team at Vercel.
Link upgraded
In NextJS 12 the Link object was a bit odd. With ReactRouter you could easily create a link
using <Link to="/Products">Products</Link>
but NextJS wanted to you to also include an anchor tag:
import Link from 'next/link';
<Link href="/Products">
<a>Products</a>
</Link>
So now in NextJS we get something more link ReactRouter:
<Link href="/about">
About
</Link>
Definitely a welcomed update as it's much simpler to write and inline with what we'd expect.
Font integration
NextJS now as a new font system that can optimise your font collection including custom fonts. This is a big help because it reduces your dependancy on external sources to store your font files and therefore removing those external file requests.
Fonts can be self-hosted with any font type, and NextJS will handle all the scaling of the fonts for you if you choose to use them on standard elements.
import {Inter} from '@next/font/google';
const inter = Inter();
<html className={inter.className}>
Personally I use Tailwind CSS for most of my work unless we have a dedicated UI design team to supply our styles, so this code above is from the official NextJS docs.
Loading UI
With the routing changes in NextJS there was also the file convention change which I spoke a little about up above. But
something that NextJS didn't do that you could
do in a CSR app was loading components. Users want to see the UI rendered fast, and the longer they wait the less
interested they will be on staying on your site or returning in future.
NextJS's changes to the file system mean that you can specify a loading.tsx
file alongside the component you want to
render and NextJS will handle the state rendering. This is useful if
you are loading larger items like images or backend data that takes a little longer than the rest of the page to render.
├── app
├── layout.tsx
├── page.tsx
└── products
├── layout.tsx
├── loading.tsx
└── page.tsx
Inside the loading.tsx you can use you own custom compnents just like you usually would
export default function Loading() {
return <LoadingComponent/>
}
Client Side Rendering
Previously in NextJS 12 everything was SSR. But with the NextJS 13 we can make a component Client Side Render by
adding use client
at the top of the file
"use client"
export default LinkedItems()
{
return <div className="linked-items">
...
</div>
}
This is a great improvement for any dynamic rendering we want to do in dashboard or other situations where you want a quick load and then populate other sections of the page post-render.
No more getServerSideProps
This was something that I found annoying. Every time a server side call was required, the getServerSideProps function had to be used. It's still available to use if you want to but now there is a much simpler way to do it, and something that those who write CSR apps will be used to.
async function getProducts() {
const res = await fetch('https://localhost:3000/getProducts');
const data = await res.json();
return data?.items as Product[];
}
export default async function Products() {
const products = await getProducts();
return <div>
{products?.map(product => <div>{product.name}</div>)}
...
</div>
}
There's so much more to talk about on this, so check out the docs on the NextJS site to read more and get your next project started with it: https://beta.nextjs.org/docs/