Skip to main content

Next.js Netlify Deployment

Introduction

Deploying your Next.js application to a production environment is a crucial step in making your web application available to users. Netlify is a popular hosting platform that offers seamless integration with Next.js, providing developers with an efficient way to deploy and manage their applications.

In this guide, we'll walk through the process of deploying a Next.js application to Netlify, covering everything from initial setup to advanced configurations. Whether you're building a simple static site or a complex application with server-side rendering, this guide will help you get your project live on Netlify.

Prerequisites

Before we begin, make sure you have:

  • A Next.js project ready for deployment
  • A GitHub, GitLab, or Bitbucket account where your code is hosted
  • A Netlify account (you can sign up for free at netlify.com)
  • Basic understanding of Next.js concepts

Understanding Netlify Deployment Options for Next.js

Netlify offers two primary ways to deploy Next.js applications:

  1. Static Site Generation (SSG): Perfect for sites that can be pre-rendered at build time
  2. Server-Side Rendering (SSR): Supported through Netlify Functions for dynamic content

Let's explore both approaches.

Method 1: Deploying a Static Next.js Site

Step 1: Configure your Next.js project

For static site deployment, you'll need to ensure your Next.js project is configured properly. Add or verify the following in your next.config.js file:

js
// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
output: 'export',
images: {
unoptimized: true, // For static export
},
}

module.exports = nextConfig

The output: 'export' configuration tells Next.js to export your application as static HTML files, which is perfect for Netlify's standard deployment.

Step 2: Create a netlify.toml file

Create a netlify.toml file in the root of your project to configure your deployment:

toml
[build]
command = "npm run build"
publish = "out"

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

This configuration tells Netlify to:

  • Run npm run build to build your project
  • Publish the contents of the out directory
  • Use the Next.js plugin for Netlify to optimize the deployment

Step 3: Update your package.json scripts

Ensure your package.json has the appropriate build script:

json
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start"
}

Step 4: Deploy to Netlify

Now you're ready to deploy your application:

  1. Push your code to your Git repository
  2. Log in to your Netlify account
  3. Click "New site from Git"
  4. Choose your Git provider (GitHub, GitLab, or Bitbucket)
  5. Select your repository
  6. Confirm the build settings
    • Build command: npm run build
    • Publish directory: out
  7. Click "Deploy site"

Netlify will now build and deploy your static Next.js site!

Method 2: Deploying a Next.js App with SSR and API Routes

For applications requiring server-side rendering or API routes, you'll need a slightly different setup.

Step 1: Install the Netlify Next.js plugin

bash
npm install -D @netlify/plugin-nextjs

Step 2: Configure netlify.toml for SSR

toml
[build]
command = "npm run build"
publish = ".next"

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

[functions]
included_files = [
"node_modules/**",
".next/**"
]

This configuration enables Netlify to handle server-side rendering by:

  • Using the Next.js plugin
  • Converting Next.js API routes and SSR pages into Netlify Functions
  • Including necessary files for the functions to work

Step 3: Deploy to Netlify

Follow the same deployment steps as before, but ensure that:

  • The publish directory is set to .next (not out)
  • The build command is set to your build script

Environment Variables

To manage secrets and configuration values, you can set environment variables in Netlify:

  1. Go to your site's dashboard in Netlify
  2. Navigate to Site settings > Build & deploy > Environment
  3. Add your environment variables

For local development, create a .env.local file (make sure to add it to .gitignore):

NEXT_PUBLIC_API_URL=https://api.example.com
SECRET_KEY=your_secret_key

For variables that should be accessible in the browser, prefix them with NEXT_PUBLIC_.

Handling Redirects and Rewrites

You can configure redirects and rewrites in your netlify.toml file:

toml
[[redirects]]
from = "/old-page"
to = "/new-page"
status = 301

[[redirects]]
from = "/api/*"
to = "/.netlify/functions/api/:splat"
status = 200

Alternatively, you can use Next.js's built-in redirects in next.config.js:

js
module.exports = {
async redirects() {
return [
{
source: '/old-page',
destination: '/new-page',
permanent: true,
},
]
},
}

Optimizing for Performance

1. Enable Caching Headers

Add custom headers in your netlify.toml file:

toml
[[headers]]
for = "/static/*"
[headers.values]
Cache-Control = "public, max-age=31536000, immutable"

[[headers]]
for = "/_next/image/*"
[headers.values]
Cache-Control = "public, max-age=31536000, immutable"

2. Use Next.js Image Optimization

For static sites, you'll need to use the unoptimized: true option as shown earlier. For SSR deployments, Netlify's Next.js plugin handles image optimization.

3. Enable Incremental Static Regeneration (ISR)

For SSR deployments, you can use Next.js's ISR feature:

jsx
// pages/products/[id].js
export async function getStaticProps({ params }) {
const res = await fetch(`https://api.example.com/products/${params.id}`)
const product = await res.json()

return {
props: { product },
revalidate: 60, // Regenerate page every 60 seconds if requested
}
}

export async function getStaticPaths() {
return {
paths: [], // Generate no pages at build time
fallback: 'blocking', // Generate pages on-demand
}
}

Real-world Example: Deploying a Next.js Blog

Let's walk through deploying a simple Next.js blog with markdown content:

Project structure:

my-blog/
├── components/
├── pages/
│ ├── index.js
│ ├── posts/
│ │ └── [slug].js
├── posts/
│ ├── hello-world.md
│ └── getting-started.md
├── next.config.js
├── netlify.toml
└── package.json

Dynamic post page:

jsx
// pages/posts/[slug].js
import { useRouter } from 'next/router'
import fs from 'fs'
import path from 'path'
import matter from 'gray-matter'
import { marked } from 'marked'

export default function Post({ post }) {
const router = useRouter()

if (router.isFallback) {
return <div>Loading...</div>
}

return (
<article>
<h1>{post.frontmatter.title}</h1>
<div dangerouslySetInnerHTML={{ __html: post.content }} />
</article>
)
}

export async function getStaticPaths() {
const files = fs.readdirSync(path.join('posts'))
const paths = files.map(filename => ({
params: {
slug: filename.replace('.md', '')
}
}))

return {
paths,
fallback: false
}
}

export async function getStaticProps({ params: { slug } }) {
const markdownWithMeta = fs.readFileSync(path.join('posts', slug + '.md'), 'utf-8')
const { data: frontmatter, content } = matter(markdownWithMeta)

return {
props: {
post: {
frontmatter,
slug,
content: marked(content)
}
}
}
}

Netlify configuration:

toml
[build]
command = "npm run build"
publish = "out"

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

[context.production.environment]
NEXT_PUBLIC_SITE_URL = "https://my-nextjs-blog.netlify.app"

Next.js configuration:

js
// next.config.js
module.exports = {
output: 'export',
trailingSlash: true,
}

After deploying with these configurations, your blog will be live with each markdown post rendered as a static HTML page.

Troubleshooting Common Issues

1. Build failures

If your build fails, check:

  • Your build script in package.json
  • The Node.js version (you can specify it in netlify.toml with NODE_VERSION)
  • Dependencies that might need external libraries
toml
[build.environment]
NODE_VERSION = "16"

2. Routing issues

If your routes aren't working:

  • Verify your netlify.toml redirects
  • Check that you're using trailingSlash: true in next.config.js for static exports
  • Ensure you're not mixing static and dynamic routes incorrectly

3. Environment variables

If environment variables aren't working:

  • Confirm they're set in Netlify's dashboard
  • Make sure client-side variables start with NEXT_PUBLIC_
  • Check that you're using process.env.VARIABLE_NAME correctly in your code

Summary

In this guide, we've covered:

  • Setting up a Next.js project for deployment on Netlify
  • Deploying both static sites and applications with server-side rendering
  • Managing environment variables and configuration
  • Handling redirects and custom headers
  • Optimizing performance
  • A real-world example of deploying a blog
  • Troubleshooting common issues

Netlify provides an excellent platform for Next.js deployments, offering the flexibility to handle both static sites and full-stack applications with server-side functionality. By following the steps outlined in this guide, you can confidently deploy and manage your Next.js applications on Netlify.

Additional Resources

Exercises

  1. Deploy a basic Next.js application with static export to Netlify.
  2. Create a Next.js application with API routes and deploy it to Netlify.
  3. Set up environment variables for development and production environments.
  4. Implement ISR with a 30-second revalidation period on a product page.
  5. Create a custom 404 page and configure proper redirects for old URLs.


If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)