LogoFreestyle
Guides

Deploying NextJS

How to deploy Next.js to Freestyle

Next.js is a popular React framework for building full-stack web applications. This guide shows you how to deploy Next.js apps to Freestyle using the v2 SDK.

Prerequisites

  • A Next.js application (create one with npx create-next-app@latest)
  • Freestyle API key from the Freestyle Dashboard
  • The Freestyle SDK installed: npm install freestyle

Configure Next.js for Deployment

Next.js defaults to a serverless bundle that requires additional configuration. You need to set the output mode to standalone and disable image optimization (since Freestyle doesn't support Sharp binaries).

Update your next.config.mjs:

next.config.mjs
const nextConfig = {
  output: "standalone", // Required for Freestyle deployment
  images: {
    unoptimized: true, // Disable Sharp image optimization
  },
};

export default nextConfig;

The standalone output mode creates a minimal production build that includes only the necessary files for deployment.

Deployment Methods

There are two primary ways to deploy Next.js apps to Freestyle:

The simplest approach is to deploy directly from your Git repository. Freestyle will automatically detect Next.js and build it for you.

Sign up at dash.freestyle.sh, create an api key, and configure it in your environment.

.env
FREESTYLE_API_KEY=your-api-key
npm i freestyle
deploy.ts
import { freestyle } from "freestyle";

async function deploy() {
  const { deployment, domains } = await freestyle.serverless.deployments.create(
    {
      repo: "https://github.com/your-username/your-nextjs-app",
      // branch: "main",        // Optional: specify branch
      // rootPath: "./web",     // Optional: for monorepos

      domains: ["my-nextjs-app.style.dev"], // Use any available *.style.dev subdomain
      build: true, // Freestyle auto-detects and builds Next.js
    },
  );

  console.log("Deployed to:", domains);
  console.log("Deployment ID:", deployment.deploymentId);
}

deploy();

For Freestyle Git repositories, you can use the repository ID directly: ts repo: "your-repo-id-here" See the Git documentation for more details.

Method 2: Deploy from Local Files

For more control over the build process, you can build locally and deploy the output using the new readFiles utility.

Step 1: Build Your Next.js App

npm run build

This creates the production build in .next/standalone, along with static assets.

Step 2: Prepare Build Artifacts

Copy the necessary files to the standalone directory:

# Copy public files
cp -r public .next/standalone/public

# Copy static assets
cp -r .next/static .next/standalone/.next/static

# Copy your lockfile (for dependency installation)
cp package-lock.json .next/standalone/package-lock.json

Replace package-lock.json with your package manager's lockfile: - npm: package-lock.json - yarn: yarn.lock - pnpm: pnpm-lock.yaml - bun: bun.lockb

Step 3: Deploy Using the SDK

Use the new readFiles utility to read all files from the standalone directory:

deploy.ts
import { freestyle } from "freestyle";
import { readFiles } from "freestyle/utils";

async function deploy() {
  // Read all files from the standalone output directory
  const files = await readFiles(".next/standalone");

  const { deployment, domains } = await freestyle.serverless.deployments.create(
    {
      files,
      entrypointPath: "server.js", // Next.js standalone entrypoint
      domains: ["my-nextjs-app.style.dev"], // Use any available *.style.dev subdomain
    },
  );

  console.log("Deployed to:", domains);
  console.log("Deployment ID:", deployment.deploymentId);
}

deploy();

The readFiles utility:

  • Automatically reads all files in the directory
  • Excludes node_modules/ (Freestyle installs dependencies separately)
  • Base64-encodes file contents for reliable transmission
  • Handles binary files correctly

Advanced Configuration

Environment Variables

Set environment variables for your Next.js app:

await freestyle.serverless.deployments.create({
  repo: "https://github.com/your-username/your-nextjs-app",
  build: true,
  domains: ["app.style.dev"],
  envVars: {
    NEXT_PUBLIC_API_URL: "https://api.example.com",
    DATABASE_URL: "postgresql://...",
  },
});

Network Permissions

Control which external domains your Next.js app can access:

await freestyle.serverless.deployments.create({
  repo: "https://github.com/your-username/your-nextjs-app",
  build: true,
  domains: ["app.style.dev"],
  networkPermissions: [
    {
      action: "allow",
      domain: "api.stripe.com",
      behavior: "exact",
    },
    {
      action: "allow",
      domain: ".*\\.amazonaws\\.com",
      behavior: "regex",
    },
  ],
});

Custom Timeout

Increase the timeout for long-running requests:

await freestyle.serverless.deployments.create({
  repo: "https://github.com/your-username/your-nextjs-app",
  build: true,
  domains: ["app.style.dev"],
  timeoutMs: 30000, // 30 seconds (default is lower)
});

Waiting for Deployment

Wait for the deployment to be fully rolled out before the API call returns:

const { deployment, domains } = await freestyle.serverless.deployments.create({
  repo: "https://github.com/your-username/your-nextjs-app",
  build: true,
  domains: ["app.style.dev"],
  waitForRollout: true, // Wait for full deployment
});

// Deployment is now ready to serve traffic
const response = await deployment.fetch();
console.log(await response.text());

Monorepo Setup

For Next.js apps in a monorepo, specify the rootPath:

await freestyle.serverless.deployments.create({
  repo: "https://github.com/your-org/monorepo",
  rootPath: "./apps/web", // Path to Next.js app
  build: true,
  domains: ["app.style.dev"],
});

Troubleshooting

Build Fails

If automatic framework detection doesn't work, you can specify build options manually:

await freestyle.serverless.deployments.create({
  repo: "https://github.com/your-username/your-nextjs-app",
  domains: ["app.style.dev"],
  build: {
    command: "npm run build",
    outDir: ".next/standalone",
    envVars: {
      NODE_ENV: "production",
    },
  },
});

Image Optimization Errors

If you see Sharp-related errors, ensure images.unoptimized is set to true in next.config.mjs.

Module Not Found

Make sure your lockfile is included in the deployment. The lockfile tells Freestyle which dependencies to install.

Next Steps

On this page

Freestyle AI

Documentation assistant

Experimental: AI responses may not always be accurate—please verify important details with the official documentation.

How can I help?

Ask me about Freestyle while you browse the docs.