Discover the new features of NextJS 12 on Qoddi app platform

Deploy your code in seconds, with no infrastructure to manage. Qoddi App Platform is free for developers! Create an account today.

In this tutorial, we will look into the newest NextJS 12 features and use them in a simple project. NextJS 12 comes with a few exciting features. The most intriguing one would be the Rust SWC compiler. Faster compile, faster refresh.


Compiling JS/TS With Rust - SWC

It’s pretty awesome how NextJS has changed how websites are built and deployed and still improve everytime to make our life easier.
Especially using the new SWC rust compiler that I don’t even notice compiling on hot reload.
SWC replaces Babel and Terser, a TS/JS compiler and a minify tool.

Thanks to SWC, build comes from 500ms to 10ms and minifying 250ms -30ms. Also, they made a CSS parsing tool using Rust. So, this is the most exciting feature, using a Rust-based compiler.

Middleware

Middleware is another new exciting feature that I can’t wait to use. Basically create a _middleware.js in any directory inside pages and it will go through each request in that directory. You can manipulate your request traffic with one file. We will be creating middleware later on this tutorial.

React.suspense and React.lazy

These two are available since Next 11 as Beta. Now, NextJS12 supports both completely. React suspense is a conditional loading tool: You can load a part of a page or component after the page loads and also you can add a condition that needs to be fulfilled before loading a component.
React.Suspense re-renders the page with new data. It triggers React.lazy to import the component. For a large page, it really helps to load only what is required for the visitor and then load content based on visitor's events. Before that we would have to pre-load everything and show them according to the visitor's behavior.
React suspense solves this problem better.

React lazy is a new way to import components inside components after the page is already loaded.

const TextField = lazy(() => import('./formFields/TextField'));

Another thing, React Suspense can show a loader while the lazy loading is working.

Plan the Simple Project

  1. We will create our NextJS project.
  2. Edit the home component
  3. Create a component that we will load with lazy loading
  4. Create a loader that will show on screen while loading
  5. A middleware to test how middleware works.

Create a NextJS project with this command and edit the index.js

npx create-next-app ./

Paste this code in index.js :

//import lazy and Suspense from react
import React, { Suspense, lazy } from "react";
import Head from "next/head";
import styles from "../styles/Home.module.css";
//load loader component
import IAmALoader from "../component/IAmALoader";
//the component to load with lazy load
const ILoadWithLazy = lazy(() => import("../component/ILoadWithLazy"));
export default function Home() {
//check if next server loading finishes and if window object initializes
const isServer = typeof window === "undefined";
return (
<div className={styles.container}>
<Head>
<title>Next 12 features</title>
<meta
name="description"
content="Generated by create next app"
/>
<link rel="icon" href="/favicon.ico" />
</Head>
<main className={styles.main}>
<h1 className={styles.title}>Let's load the lazy one</h1>
{
//start suspense code if window object available
!isServer && (
<Suspense fallback={<IAmALoader />}>
<ILoadWithLazy />
</Suspense>
)
}
</main>
</div>
);
}

Follow the comments in the above code. We loaded React, lazy, and Suspense from React. Then we loaded the loader component, ‘IAmLoader’ and we used React.lazy and loaded the component ‘ILoadWithLazy’.

Then, inside our component, we checked if NextJS has finished loading the page and window object is available with the isServer variable.

Now, inside our return component:

{
//start suspense code if window object available
!isServer && (
<Suspense fallback={<IAmALoader />}>
<ILoadWithLazy />
</Suspense>
)
}

We checked if the window object is available and we started Suspense. Suspense takes a fallback component which runs until the page loading finishes. Inside Suspense, we put our components that need to be rendered with lazy loading.

Let’s create a component folder outside of our pages folder and create two files,

IAmLoader.js, paste this code in it:

const IAmALoader = () => {
return <p>Loading</p>;
};
export default IAmALoader;

ILoadWithLazy.js, use this code in it:

const ILoadWithLazy = () => {
return (
<div className="loaded-comp">
<h1>I loaded last because I am lazy.</h1>
</div>
);
};
export default ILoadWithLazy;

We just used React.lazy and React.Suspense. But in a local environment, it will be too fast to be noticed. We may not see if it’s loading lazily on a local server. So, let’s quickly start a server on Qoddi app platform and test our code. For more information on how Qoddi deploys NodeJS apps, visit: https://devcenter.qoddi.com/node-js/

Deploy to Qoddi

Qoddi supports Next 12 out of the box.
Go to your Qoddi dashboard and create a new app.

Next, click on the GitHub button, and select your repository from the dropdown. Go next and select the branch name.

And finally, launch your app. Now, while Qoddi builds your app, let’s add the middleware features.

Next 12 Middleware

Add a _middleware.js in your pages folder, this will run on each request to the website because it is on the main pages directory. You can also have middlewares in other directories that will run only on pages placed under that same directory. That means middleware in NextJS follows the top-down rule. It runs for each request below the folder, not above.

const FirstMiddleware = (req, ev) => {
const checkNothing = true;
if (!checkNothing) {
return new Response("Hello World");
}
return console.log("hi");
};
export default FirstMiddleware;

Now, also push this code to git. Q0ddi will detect the change, and rebuild your app with your new code without you doing anything.
This will log to the console on each request. But, if you have checkNothing to false, it will return Hello World to the browser and won’t show any page on any route.