How to deploy Next.js applications with SSR and API routes
Next.js applications present unique deployment considerations because they support multiple rendering strategies within a single framework. These include static generation, server-side rendering (SSR), API routes, and Incremental Static Regeneration (ISR)—which allows you to update static pages after deployment without rebuilding the entire site. Render provides flexible infrastructure that accommodates these different modes, but you'll need to understand how your Next.js architecture maps to Render's service types and configuration options.
This guide teaches deployment patterns through focused examples that illustrate core concepts. You'll learn to make informed decisions about service architecture, understand how rendering modes affect configuration, and recognize how Next.js-specific features interact with Render's infrastructure.
Prerequisites and environment requirements
Before deploying Next.js applications to Render, verify your local environment meets these requirements:
- Next.js Version: Next.js 16 or later.
- Node.js Version: Node.js 20.x (Active LTS) or 22.x (Current LTS). Specify your required version explicitly using a
.node-versionfile orenginesfield inpackage.jsonto ensure build consistency. - Repository Access: Your Next.js application must be in a Git repository (GitHub, GitLab, or Bitbucket) with Render authorized to access it.
- Build Verification: Run
npm run buildlocally and confirm it completes without errors. - Environment Variable Inventory: Document which environment variables your application requires at build time (prefixed with
NEXT_PUBLIC_) versus runtime (used in API routes orgetServerSidePropsin Pages Router, or server components in App Router).
App Router vs. Pages Router considerations
Next.js 13+ introduced the App Router, which changes how routing and data fetching work. This guide covers deployment principles that apply to both, but specific configuration patterns may vary:
- App Router (recommended): Uses React Server Components by default. API routes are defined in
route.jsfiles. - Pages Router: Uses
getServerSidePropsfor SSR andgetStaticPropsfor static generation. API routes are defined inpages/api.
Most Render configuration (service types, build commands, environment variables) remains consistent across both routers. The primary difference lies in how you implement data fetching and caching logic within your application code.
Understanding Next.js deployment models on Render
You can deploy your Next.js applications on Render as either Static Sites or Web Services, depending on your application's rendering requirements.
Static Site Deployment
When your Next.js application uses only static generation and you've configured output: 'export' in next.config.js, you can deploy it as a static site. This model can't support SSR, ISR, or API routes because there's no Node.js server running after deployment.
Web Service Deployment (Standard)
Applications using server-side rendering, ISR, API routes, or Next.js middleware require a persistent Node.js process. You'll deploy these as Web Services, executing next start to run Next.js's production server.
This simplified render.yaml demonstrates the minimal configuration for a Next.js application with SSR:
Web Service Deployment (Standalone)
For optimized containerized or cloud deployments, Next.js offers output: 'standalone'. This creates a minimal folder at .next/standalone containing only the necessary files for production, significantly reducing the deployment size.
Enable it in next.config.js:
Update your render.yaml start command:
Note: When using standalone mode, you may need to copy your public and .next/static folders to the standalone directory or configure your CDN to serve them, as the minimal server does not serve these by default. For most standard Render Web Service deployments, the default next start is sufficient and simpler.
Static sites vs. SSR configuration
The next build command produces fundamentally different outputs depending on your configuration in next.config.js. This setting determines which Render service type you should use:
- Static Export (
output: 'export'): Generates a purely static site in theoutdirectory (HTML/CSS/JS). This output contains no server-side code and requires only a CDN or static file server.- Target Service: Static Site
- Standard Build (Default): Creates a
.nextdirectory containing both pre-rendered static pages and the Node.js server required for SSR, API routes, and ISR.- Target Service: Web Service
- Standalone Build (
output: 'standalone'): Creates an optimized.next/standalonedirectory containing only the necessary files for production. This is ideal for reducing deployment size.- Target Service: Web Service (with modified start command)
For a fully static Next.js site using output: 'export':
Render Advantage: Zero-Downtime Deploys
Render's Zero-Downtime Deploys ensure that your Next.js application remains available during updates. Render spins up a new instance of your service, waits for it to pass health checks, and only then switches traffic over from the old instance. This is critical for SSR apps where a restart would otherwise drop active requests.
Environment variables: build-time vs. runtime
Next.js's environment variable system distinguishes between build-time and runtime variable injection, affecting your Render configuration and security considerations.
- Build-Time Variables: Variables prefixed with
NEXT_PUBLIC_get embedded into JavaScript bundles duringnext build. These values become part of your client-side code, visible to anyone who inspects your application. - Runtime Variables: Variables used exclusively in API routes,
getServerSideProps, or server-side configuration remain on the server and can safely contain secrets.
Configuration pattern in render.yaml:
Note that sync: false prevents the value from being overwritten by the blueprint. You must set these sensitive values (like database passwords or API secrets) manually in the Render Dashboard, which is a security best practice.
Configuring Health Checks
Render uses health checks to achieve zero-downtime deploys. Create a simple API route that returns a 200 OK status:
Configure healthCheckPath in your render.yaml:
Render will verify this endpoint is responsive before directing traffic to the new instance.
Render Advantage: Native Secrets Management
Use Environment Groups to manage shared configuration across multiple services (e.g., your Next.js frontend and a Python worker). For sensitive files, use Secret Files to securely inject certificates or keys at runtime without committing them to Git.
Configuring Next.js image optimization
Next.js Image Optimization requires server-side processing and interacts with Render's infrastructure in specific ways.
The optimization process requires persistent disk for cache. Optimized images cache in .next/cache/images. On Render's Web Services, the default ephemeral filesystem means cached images are lost with each deploy or restart.
You can solve this problem with Render's Persistent Disks:
External Image Source Configuration: Configure next.config.js to allow external sources:
Handling incremental static regeneration (ISR)
ISR allows pages to update after deployment without full rebuilds.
When a request hits an ISR page after its revalidation period expires, Next.js serves the stale cached page immediately while triggering background regeneration. This process relies on writing to the filesystem (specifically .next/cache).
Critical Requirement: Because Render Web Services have ephemeral filesystems, the ISR cache will be lost on every deploy or restart unless you configure a Persistent Disk. Follow the same disk configuration pattern shown in the Image Optimization section above to mount a disk at /opt/render/project/src/.next/cache.
On-Demand Revalidation: Next.js supports programmatic page invalidation:
Example next.config.js configuration
Here is a complete next.config.js example combining the optimization and deployment features discussed:
Common deployment issues
-
Build Failures with "Module not found": Verify
package.jsonincludes all required dependencies and ensure your lockfile (package-lock.jsonoryarn.lock) is committed to your repository. -
Port Binding Errors: By default,
next startbinds to0.0.0.0and the port defined by Render'sPORTenvironment variable, so no extra configuration is needed.However, if you are using a custom server (e.g.,
server.jswith Express/Node http), you must explicitly readprocess.env.PORTand bind to0.0.0.0:
- Memory Exhaustion During Builds: If your build fails with OOM errors, increase Node.js heap size using an environment variable:
- "Invalid src prop" Image Errors: Add external domains to your
next.config.jsimage configuration as shown in the Image Optimization section. - 504 Gateway Timeouts: While Render supports long-running requests (up to 100 minutes), 504 errors usually indicate that your application is hanging or crashing before sending a response. Check your logs for unhandled exceptions or infinite loops in
getServerSideProps. Also ensure your Node.js server (if custom) isn't enforcing its own shorter timeout.
Monorepo configuration
For monorepos (using tools like Turborepo or Nx), specify the root directory where your Next.js application resides:
Production considerations
Render Advantage: Preview Environments
Enable Pull Request Previews to automatically deploy a temporary instance of your Next.js app for every pull request. This allows your team to test API routes, UI changes, and full end-to-end flows in a production-like environment before merging code.
-
Custom Domains and SSL: Render automatically provisions and renews free TLS certificates for Custom Domains. All HTTP traffic is automatically redirected to HTTPS.
-
Database Connections: Implement connection pooling to prevent exhausting database connections. When using serverless functions or API routes, global connection objects are essential.
Example using
pg: -
Middleware Behavior: Next.js Middleware runs as a standard Node.js process on Render Web Services, not in a specialized "Edge Runtime" environment. This means you have access to the full Node.js API, but you should still keep middleware lightweight to avoid latency on every request.
-
Auto-Scaling: SSR workloads can be CPU-intensive. Enable Render's autoscaling to automatically add instances during traffic spikes and scale down during quiet periods, ensuring consistent performance without over-provisioning.
-
Monitoring: Integrate application monitoring and structured logging for production issue diagnosis. Render's log streams can be sent to Datadog, LogDNA, or other providers.
The patterns in this guide form a foundation for adapting to your specific Next.js architecture. Understanding how rendering modes, environment variables, and Next.js features interact with Render's infrastructure enables you to make informed configuration decisions that optimize for your application's requirements.
Next steps
- Explore the Next.js Documentation for deeper dives into App Router, data fetching, and advanced caching strategies.
- Check out Render's Next.js Guide for platform-specific tutorials and quickstarts.