Learn how to ship impactful customer journeys with Builder

Announcing Visual Copilot - Figma to production in half the time

Builder.io logo
Contact Sales
Platform
Developers
Contact Sales

Blog

Home

Resources

Blog

Forum

Github

Login

Signup

×

Visual CMS

Drag-and-drop visual editor and headless CMS for any tech stack

Theme Studio for Shopify

Build and optimize your Shopify-hosted storefront, no coding required

Resources

Blog

Get StartedLogin

‹ Back to blog

Web Development

Server-only Code in Next.js App Router

April 3, 2024

Written By Vishwas Gopinath

The React Server Components architecture which categorizes components into Client and Server types, was integrated with Next.js's App Router. When developing with the app router, distinguishing between server-only and client-side code is crucial for the application's security, performance, and maintainability. This blog post will cover defining server-only code in a Next.js application.

Understanding server-only code

Server-only code in Next.js refers to code that is intended to be executed only on the server side. This might include modules or functions that:

  • Use server-specific libraries.
  • Access environment variables containing sensitive information.
  • Interact with databases or external APIs.
  • Process confidential business logic.

The challenge arises because JavaScript modules can be shared between server and client components, leading to the unintentional inclusion of server-side code in the client bundle. This inclusion can expose sensitive data, increase the bundle size, and lead to potential security vulnerabilities.

Let's walk through a hands-on example to demonstrate server-only code. Start by creating a Next.js application using create-next-app. Then, within a new src/utils directory that you create, add a file named server-utils.ts. This file will contain the following server-side function:

// src/utils/server-utils.ts
export const serverSideFunction = () => {
  console.log(
    `Using multiple libraries,
     accessing environment variables,
     interacting with a database,
     processing confidential information`
  );
  return "Server-side result";
};

Imagine this function uses various NPM packages, accesses API keys, retrieves data from a database, and processes sensitive algorithms. Such a function should never be exposed to the client side.

Now, let's use this function in a server component, like an About page component:

// pages/about.tsx
import { serverSideFunction } from "@/utils/server-utils";

const About = () => {
  const result = serverSideFunction();
  console.log(result);
  return <div>About Page</div>;
};

export default About;

Navigating to the /about route, you'll observe log messages in the server terminal, not in the browser, indicating that our code is server-only.

However, what if this function is mistakenly imported into a client component, such as a Dashboard page? The code might not work, either partially or completely. This is where the server-only package comes into play.

To safeguard our application, we install the server-only package:

npm i server-only

We then modify our server-utils.ts to include this package:

// src/utils/server-utils.ts
import 'server-only';

export const serverSideFunction = () => {
  console.log(
    `Using multiple libraries,
     accessing environment variables,
     interacting with a database,
     processing confidential information`
  );
  return "Server-side result";
};

Now, if someone tries to import serverSideFunction into a client component, the build process will throw an error, preventing the leak of server-side code to the client.

Just as server-only code needs isolation, client-only code that interacts with browser-specific features like the DOM, the window object, localStorage etc must also be confined to the client side to leverage browser-specific features effectively.

The client-only package serves as a guardrail, ensuring that our client-side code remains where it belongs.

Maintaining a clear boundary between server-only and client-side code is essential in Next.js applications. It ensures your application's integrity, security, and user experience. Use the server-only and client-only packages and follow best practices to reinforce this separation and safeguard your application.

Introducing Visual Copilot: convert Figma designs to high quality code in a single click.

Try Visual Copilot

Share

Twitter
LinkedIn
Facebook
Hand written text that says "A drag and drop headless CMS?"

Introducing Visual Copilot:

A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot
Newsletter

Like our content?

Join Our Newsletter

Continue Reading
AI8 MIN
How to Build Reliable AI Tools
November 15, 2024
Web Design11 MIN
Design Smarter with Figma Auto Layout
November 13, 2024
Web Development10 MIN
A Guide to Server-Side Rendering
November 12, 2024