⚡ TECH BLOG
Home
Blog
Tags
About
⚡

Powered by Next.js 15 & Modern Web Tech ⚡

Back to Home

Next.js 12: New Features and Improvements

January 15, 2022
nextjsreactjavascriptwebdev
Next.js 12: New Features and Improvements

Next.js 12: New Features and Improvements

Next.js 12 brings significant performance improvements and exciting new features. Let's explore what's new.

Rust Compiler

Next.js 12 replaces Babel with a Rust-based compiler for faster builds.

Performance Gains

# Up to 17x faster compilation
# Up to 5x faster fresh builds
# Up to 2x faster hot module replacement

JSX Transformation

// Automatic JSX transform - no React import needed
function App() {
  return <h1>Hello World</h1>;
}

// Before: import React from 'react';
// Now: Works without import

Middleware

Middleware allows you to run code before a request completes.

Basic Middleware

// middleware.js
import { NextResponse } from 'next/server';

export function middleware(request) {
  // Check authentication
  const isAuthenticated = request.cookies.get('token');
  
  if (!isAuthenticated && request.nextUrl.pathname.startsWith('/dashboard')) {
    return NextResponse.redirect(new URL('/login', request.url));
  }
  
  return NextResponse.next();
}

export const config = {
  matcher: '/dashboard/:path*',
};

Rewrites and Headers

export function middleware(request) {
  const response = NextResponse.next();
  
  // Add custom header
  response.headers.set('x-custom-header', 'value');
  
  // Rewrite URL
  if (request.nextUrl.pathname.startsWith('/old-blog')) {
    return NextResponse.rewrite(new URL('/blog', request.url));
  }
  
  return response;
}

Enhanced Image Optimization

import Image from 'next/image';

// New placeholder feature
<Image
  src="/hero.jpg"
  alt="Hero"
  width={1200}
  height={800}
  placeholder="blur"
  blurDataURL="data:image/jpeg;base64,..."
/>

// Remote images
<Image
  src="https://example.com/image.jpg"
  alt="Remote"
  width={500}
  height={300}
/>

// next.config.js - allow domains
module.exports = {
  images: {
    remotePatterns: [
      {
        protocol: 'https',
        hostname: 'example.com',
      },
    ],
  },
};

AVIF Support

// next.config.js
module.exports = {
  images: {
    formats: ['image/avif', 'image/webp'],
  },
};

URL Imports

Import packages directly from URLs:

// import from URL
import confetti from 'https://cdn.skypack.dev/canvas-confetti';

confetti();

// next.config.js
module.exports = {
  experimental: {
    urlImports: ['https://cdn.skypack.dev'],
  },
};

React 18 Support

Automatic Batching

function App() {
  const [count, setCount] = useState(0);
  const [flag, setFlag] = useState(false);

  function handleClick() {
    // React 18 batches these automatically
    setCount(c => c + 1);
    setFlag(f => !f);
    // Only one re-render
  }
}

startTransition

import { startTransition } from 'react';

function SearchInput() {
  const [query, setQuery] = useState('');
  const [results, setResults] = useState([]);

  const handleChange = (e) => {
    // Urgent update
    setQuery(e.target.value);
    
    // Non-urgent update
    startTransition(() => {
      setResults(searchResults(e.target.value));
    });
  };
}

Suspense

import { Suspense } from 'react';

function App() {
  return (
    <Suspense fallback={<Loading />}>
      <DataComponent />
    </Suspense>
  );
}

// With lazy loading
const LazyComponent = lazy(() => import('./LazyComponent'));

function App() {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <LazyComponent />
    </Suspense>
  );
}

Data Fetching Improvements

SWC and Jest

// jest.config.js
const nextJest = require('next/jest');

const createJestConfig = nextJest({
  dir: './',
});

module.exports = createJestConfig({
  testEnvironment: 'jest-environment-jsdom',
});

API Routes Improvements

// pages/api/user.js
export default function handler(req, res) {
  res.status(200).json({ name: 'John Doe' });
}

// With middleware
export const config = {
  api: {
    bodyParser: {
      sizeLimit: '1mb',
    },
  },
};

Streaming SSR

import { Suspense } from 'react';

function StreamingPage() {
  return (
    <div>
      <h1>Streaming SSR</h1>
      <Suspense fallback={<p>Loading...</p>}>
        <SlowComponent />
      </Suspense>
    </div>
  );
}

Bot-Aware ISR Fallback

// pages/blog/[slug].js
export async function getStaticPaths() {
  return {
    paths: [],
    fallback: 'blocking', // Better for bots
  };
}

TypeScript Improvements

// Better type inference
import type { GetStaticProps, NextPage } from 'next';

interface Post {
  id: string;
  title: string;
}

interface Props {
  posts: Post[];
}

export const getStaticProps: GetStaticProps<Props> = async () => {
  const posts = await getPosts();
  return {
    props: { posts },
  };
};

const Blog: NextPage<Props> = ({ posts }) => {
  return (
    <ul>
      {posts.map(post => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  );
};

export default Blog;

ESM Support

// package.json
{
  "type": "module"
}

// Or use .mjs extension
// utils/helper.mjs
export function formatDate(date) {
  return new Intl.DateTimeFormat('en-US').format(date);
}

Edge Runtime

// pages/api/hello.js
export const config = {
  runtime: 'edge',
};

export default function handler(request) {
  return new Response(JSON.stringify({ name: 'John' }), {
    headers: { 'content-type': 'application/json' },
  });
}

Performance Monitoring

// pages/_app.js
export function reportWebVitals(metric) {
  console.log(metric);
  // Send to analytics
  fetch('/api/analytics', {
    method: 'POST',
    body: JSON.stringify(metric),
  });
}

Upgrading to Next.js 12

# Update package.json
npm install next@12 react@18 react-dom@18

# Or use the upgrade CLI
npx @next/codemod@canary upgrade 12

Breaking Changes

  1. Minimum Node.js version: 12.22.0
  2. Minimum React version: 17.0.2
  3. Image component changes: layout prop replaced with style
  4. Webpack 5 required: No longer supports Webpack 4

Conclusion

Next.js 12 brings significant improvements in performance, developer experience, and features. The Rust compiler, middleware, and React 18 support make it a compelling upgrade for any project.

Share:

💬 Comments