5 Tips and Tricks To Make Your Life With Next.js 14 Easier

Skanda Aryal
4 min readMay 11, 2024

--

Next.js 14 is a powerful React framework that simplifies the process of building server-rendered React applications. However, with its advanced features and conventions, there can be some confusion and ambiguity for developers, especially those new to the framework. In this blog post, we’ll explore five tips and tricks to help make your life with Next.js 14 easier.

Tip 1: Working with Next.js Images

One area of confusion is the handling of images in Next.js. The process differs depending on whether you’re working with local or remote images.

Local Images

Local Image in Next.js

For local images, you don’t need to specify a width and height. Next.js will automatically identify the dimensions. Simply import the image and render it using the `next/image` component.

import Image from "next/image";
import localImage from "public/hoy.png";
export default function MyComponent() {
return <Image src={localImage} alt="Local Image" />;
}

Remote Images

For remote images, you need to provide a blur placeholder and specify the width and height to prevent layout shifts. You can use the `placeholder=”blur”` prop to show a blurred version of the image until the full image loads.

To generate the blur data URL for remote images, you can use the `sharp` and `placeholder` packages:

import Image from "next/image";
import getBase64 from "./utils/getBase64";
export default async function MyComponent() {
const blurDataUrl = await getBase64(remoteImageUrl);
return (
<Image
src={remoteImageUrl}
width={600}
height={600}
alt="Remote Image"
placeholder="blur"
blurDataURL={blurDataUrl}
/>
);
}

The `getBase64` utility function fetches the remote image, converts it to an ArrayBuffer, and then generates the base64 representation using the `placeholder` package.

Tip 2: Handling Environment Variables

Be careful when marking environment variables with `next.config.env.NEXT_PUBLIC_*` as these variables will be exposed in the browser and included in the JavaScript bundle. If you have sensitive API keys or secrets, make sure not to prefix them with `NEXT_PUBLIC_`, then they will only be available in a Node.js environment.

Tip 3: Understanding Caching in Next.js

Next.js caching behavior differs between development and production environments. In development mode, pages are rendered dynamically on every request by default. However, in production mode, Next.js attempts to render pages statically.

To control caching in production, you can use the `revalidate` option or mark a page as `dynamic` explicitly.

// Revalidate every 5 seconds
export const revalidate = 5
// Force dynamic rendering
export const dynamic = 'force-dynamic'

Tip 4: Fetching Data in Server Components

Avoid using API route handlers solely to fetch data for your server components. Instead, fetch the data directly within the server component. This approach allows Next.js to optimize the caching and reuse of data across multiple server components.

If you need to reuse the same fetch logic across multiple components, consider creating a server action in the `server/` directory.

export async function getJoke() {
const res = await fetch("https://api.example.com/joke");
const data = await res.json();
if (res.ok) {
return { success: true, joke: data.joke };
} else {
return { error: data.error };
}
}
// app/page.jsx
import { getJoke } from "../server/actions";
export default async function Page() {
const { success, joke, error } = await getJoke();
if (success) {
return <div>{joke}</div>;
} else {
throw new Error(error);
}
}

Tip 5: Understanding Client and Server Components

By default, pages in Next.js are server components. You can render client components within server components to add interactivity.

"use client";
import { useState } from "react";
export default function ClientComponent() {
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}

Child components rendered within a client component automatically become client components as well, without the need for the `’use client’` directive.

When working with providers (e.g., a theming provider), wrap the children with the provider in your layout, and the children will still be rendered as server components.

// app/layout.jsx
import { ThemeProvider } from "your-theme-library";
export default function RootLayout({ children }) {
return <ThemeProvider>{children}</ThemeProvider>;
}

Conclusion

Next.js 14 is a powerful and feature-rich framework that streamlines the development of server-rendered React applications. While it introduces some new concepts and conventions, following the tips and tricks outlined in this blog post should help you navigate through the potential areas of confusion and ambiguity.

By understanding how to work with images, handle environment variables, manage caching, fetch data in server components, and differentiate between client and server components, you’ll be better equipped to build robust and efficient applications with Next.js 14.

Remember, practice and experience are key to mastering any new technology. Don’t hesitate to explore the Next.js documentation, join the community forums, and experiment with the framework’s features to solidify your understanding further.

--

--