---
title: "Deploy Next.js 16 to Netlify - SSR Guide for Builder.io"
slug: "deploy-nextjs-16-netlify-builder-io-ssr"
published: "2026-01-21"
updated: "2026-04-06"
categories:
  - "Next.js"
tags:
  - "Next.js 16 Netlify deployment"
  - "Builder.io preview mode"
  - "server-side rendering Next.js"
  - "@netlify/plugin-nextjs"
  - "netlify.toml"
  - "NEXT_PUBLIC_BUILDER_IO_PUBLIC_KEY"
  - "force-dynamic fetchOneEntry"
  - "Turbopack"
  - "serverless functions Netlify"
  - "dynamic rendering Builder.io"
llm-intent: "how-to"
audience-level: "intermediate"
llm-purpose: "Deploy Next.js 16 to Netlify with SSR to fetch Builder.io content and enable preview mode. Update next.config, add netlify.toml, install plugin, set env…"
llm-prereqs:
  - "Next.js 16"
  - "Builder.io"
  - "Netlify"
  - "@netlify/plugin-nextjs"
  - "Turbopack"
  - "pnpm"
  - "TypeScript"
  - "Git"
---

**Summary Triples**
- (Deploy Next.js 16 to Netlify - SSR Guide for Builder.io, expresses-intent, how-to)
- (Deploy Next.js 16 to Netlify - SSR Guide for Builder.io, covers-topic, Next.js 16 Netlify deployment)
- (Deploy Next.js 16 to Netlify - SSR Guide for Builder.io, provides-guidance-for, Deploy Next.js 16 to Netlify with SSR to fetch Builder.io content and enable preview mode. Update next.config, add netlify.toml, install plugin, set env…)

### {GOAL}
Deploy Next.js 16 to Netlify with SSR to fetch Builder.io content and enable preview mode. Update next.config, add netlify.toml, install plugin, set env…

### {PREREQS}
- Next.js 16
- Builder.io
- Netlify
- @netlify/plugin-nextjs
- Turbopack
- pnpm
- TypeScript
- Git

### {STEPS}
1. Remove static export from config
2. Create async Server Component page
3. Use Builder.io fetchOneEntry correctly
4. Configure netlify.toml with plugin
5. Install Netlify Next.js plugin locally
6. Set Builder.io env variable on Netlify
7. Push to Git and verify deploy

<!-- llm:goal="Deploy Next.js 16 to Netlify with SSR to fetch Builder.io content and enable preview mode. Update next.config, add netlify.toml, install plugin, set env…" -->
<!-- llm:prereq="Next.js 16" -->
<!-- llm:prereq="Builder.io" -->
<!-- llm:prereq="Netlify" -->
<!-- llm:prereq="@netlify/plugin-nextjs" -->
<!-- llm:prereq="Turbopack" -->
<!-- llm:prereq="pnpm" -->
<!-- llm:prereq="TypeScript" -->
<!-- llm:prereq="Git" -->

# Deploy Next.js 16 to Netlify - SSR Guide for Builder.io
> Deploy Next.js 16 to Netlify with SSR to fetch Builder.io content and enable preview mode. Update next.config, add netlify.toml, install plugin, set env…
Matija Žiberna · 2026-01-21

I was building a massage therapy website with Next.js 16 and Builder.io CMS when I hit a frustrating wall. Every deployment guide I found recommended using `output: export` for static builds, but that completely broke my ability to fetch dynamic content from Builder.io. After hours of troubleshooting build errors and 404s on Netlify, I discovered the correct approach: **Server-Side Rendering with Netlify's serverless functions**. This guide walks you through the exact process I developed to get it working.

## Understanding the Core Problem

When you deploy Next.js to Netlify, you have two options: static export or server-side rendering. Most guides default to static export because it's simpler and faster to serve. However, if you're using a headless CMS like Builder.io that requires fetching content dynamically at request time, static export won't work.

The issue stems from how Builder.io's preview mode and content fetching work. The `fetchOneEntry()` function needs to read URL query parameters (`searchParams`) at request time to detect preview mode and fetch the correct content. This can't happen during a static build—it must happen when someone visits your site. That's why you need Server-Side Rendering.

## Step 1: Remove Static Export from Your Configuration

First, we need to make sure your Next.js configuration doesn't force static export. This is the root cause of most deployment failures with CMS integrations.

```typescript
// File: next.config.ts
import type { NextConfig } from "next";

const nextConfig: NextConfig = {
  turbopack: {},
};

export default nextConfig;
```

The key here is the absence of `output: 'export'`. By leaving this out, Next.js defaults to SSR mode, which allows your application to render pages on-demand when users request them. The `turbopack: {}` configuration enables Turbopack (Next.js 16's default bundler) without any custom configuration—Netlify will handle the heavy lifting.

If you previously had `output: 'export'` in your config, remove it completely. This single change is what allows Netlify to set up serverless functions for your application.

## Step 2: Set Up Your Page Component for Dynamic Rendering

Your homepage needs to be an async Server Component that can fetch content dynamically from Builder.io. Here's the correct setup:

```typescript
// File: src/app/page.tsx
import {
  Content,
  fetchOneEntry,
  getBuilderSearchParams,
  isPreviewing,
} from "@builder.io/sdk-react";
import type { Metadata } from "next";

interface PageProps {
  searchParams: Promise<Record<string, string>>;
}

const PUBLIC_API_KEY = process.env.NEXT_PUBLIC_BUILDER_IO_PUBLIC_KEY!;

export const metadata: Metadata = {
  title: "Your Site Title",
  description: "Your site description",
};

export const dynamic = 'force-dynamic';

export default async function HomePage(props: PageProps) {
  const urlPath = "/";
  const searchParams = await props.searchParams;

  const content = await fetchOneEntry({
    options: getBuilderSearchParams(searchParams),
    apiKey: PUBLIC_API_KEY,
    model: "page",
    userAttributes: { urlPath },
  });

  const canShowContent = content || isPreviewing(searchParams);

  if (!canShowContent) {
    return (
      <div className="min-h-screen flex items-center justify-center bg-white">
        <div className="text-center max-w-md mx-auto p-8">
          <h1 className="text-3xl font-bold text-gray-900 mb-4">
            Welcome to Your Site
          </h1>
          <p className="text-gray-600 mb-6">
            This page is powered by Builder.io and is currently being set up.
          </p>
        </div>
      </div>
    );
  }

  return (
    <Content
      content={content}
      apiKey={PUBLIC_API_KEY}
      model="page"
    />
  );
}
```

The crucial lines here are `export const dynamic = 'force-dynamic'` and `const searchParams = await props.searchParams`. These tell Next.js that this page cannot be statically rendered—it must be rendered on every request. This is necessary because Builder.io's preview parameters change based on the URL, and we need to detect those at runtime.

Also note: we've removed any imports of `@builder.io/widgets` which can cause bundling issues with Turbopack. If you need widgets, they'll be loaded dynamically through Builder.io's content model.

## Step 3: Configure Netlify with the Next.js Plugin

Netlify has an official plugin that handles all the complexity of running Next.js applications with serverless functions. This is what transforms your build into something Netlify can execute.

```toml
# File: netlify.toml
[build]
  command = "pnpm build"
  publish = ".next"

[[plugins]]
  package = "@netlify/plugin-nextjs"
```

The `build` section tells Netlify:

- **command**: Use `pnpm build` to compile your Next.js application (adjust to `npm run build` if you use npm)
- **publish**: Deploy the `.next` folder which contains your compiled application

The `[[plugins]]` section activates the Netlify Next.js plugin. This plugin automatically creates serverless functions for your dynamic pages and configures the routing to work correctly on Netlify's infrastructure.

## Step 4: Install the Netlify Plugin Locally

You need to install the plugin as a dev dependency so Netlify knows it exists when building:

```bash
pnpm add -D @netlify/plugin-nextjs
```

This adds the package to your `package.json`, and when you push to Git, Netlify will install it during the build process. The plugin will then do the magic of converting your `.next` build output into serverless functions.

## Step 5: Configure Environment Variables on Netlify

Your Builder.io API key needs to be available during runtime. Since environment variables in `.env` files are never pushed to production for security reasons, you must set them directly in Netlify.

Go to your Netlify dashboard:

1. Select your site
2. Navigate to **Site settings** → **Build & deploy** → **Environment**
3. Click **Add environment variable**
4. Set the variable name to `NEXT_PUBLIC_BUILDER_IO_PUBLIC_KEY`
5. Paste your public API key from Builder.io as the value

The `NEXT_PUBLIC_` prefix is crucial—it tells Next.js to make this variable available to your application code (both server and client). Without this prefix, the variable won't be accessible.

## Step 6: Push to Git and Deploy

Once your code is ready, push everything to your Git repository:

```bash
git add .
git commit -m "Configure Next.js 16 for Netlify deployment with Builder.io"
git push origin main
```

Netlify automatically detects the push and starts building your application. During the build:

1. It installs dependencies (including the `@netlify/plugin-nextjs` plugin)
2. Runs `pnpm build` to compile your Next.js application
3. The plugin converts your application into serverless functions
4. Netlify deploys the functions and static assets

You can watch the build progress in your Netlify dashboard under **Deploys**. Look for the build log to confirm the plugin ran successfully—you should see output about creating functions.

## Troubleshooting Common Issues

**Getting 404 errors after deployment?** This usually means either the plugin didn't run or your environment variable isn't set. Check:

- The build log shows "0 new function(s) to upload"? The plugin didn't run. Make sure your `netlify.toml` file was pushed to Git.
- Your page renders but has no content? Check that your `NEXT_PUBLIC_BUILDER_IO_PUBLIC_KEY` is set in Netlify's environment variables and the build used the updated config.

**Build failing with `createContext is not a function`?** This was likely caused by importing `@builder.io/widgets` directly. Remove that import and let Builder.io load widgets through your content model instead.

**Still seeing 404 on the homepage?** Ensure you have at least one page published in Builder.io with the URL set to `/`. Without published content, there's nothing for the application to render.

## What You've Now Accomplished

You've set up a Next.js 16 application that:

- Uses Server-Side Rendering to dynamically fetch content from Builder.io
- Supports preview mode so you can see unpublished content while editing
- Deploys to Netlify with zero additional configuration beyond the plugin
- Scales automatically with serverless functions—no servers to manage

The key insight here is understanding why static export doesn't work for CMS platforms. By embracing SSR instead of fighting it, you get a more powerful, maintainable deployment that properly supports your content management workflow.

Let me know in the comments if you have questions, and subscribe for more practical development guides.

Thanks, Matija