How to Fix 404 Errors When Deploying Remix Apps to Vercel

Configure the official Vercel Remix preset to enable server-side routing and eliminate 404s

·Matija Žiberna·
How to Fix 404 Errors When Deploying Remix Apps to Vercel

I was working on a Remix application that worked perfectly in development, but after deploying to Vercel I kept getting 404 errors on routes like /admin/login. The app would build successfully, but any direct navigation to routes would fail with a 404, even though the same routes worked fine locally.

After digging through Vercel's documentation and dealing with several deployment failures, I discovered the solution lies in properly configuring Remix for Vercel's serverless environment using their official tools. This guide walks you through the exact steps to eliminate those frustrating 404s.

The Root Problem

Vercel needs to understand how to handle Remix's server-side rendering and routing. By default, Vercel treats your deployment as static files, but Remix routes require server-side processing. Without proper configuration, Vercel doesn't know that routes like /admin/login should be handled by your Remix application.

Step 1: Install the Official Vercel Remix Package

The key to solving this is using Vercel's official Remix integration. Install the @vercel/remix package:

pnpm add @vercel/remix

This package provides Vercel-specific utilities and, most importantly, a Vite preset that configures everything needed for proper deployment.

Step 2: Configure the Vercel Preset in Vite

Update your vite.config.ts to include the Vercel preset:

// File: vite.config.ts
import { vitePlugin as remix } from "@remix-run/dev";
import { installGlobals } from "@remix-run/node";
import { defineConfig, type UserConfig } from "vite";
import tsconfigPaths from "vite-tsconfig-paths";
import { vercelPreset } from "@vercel/remix/vite";

installGlobals({ nativeFetch: true });

export default defineConfig({
  plugins: [
    remix({
      presets: [vercelPreset()],
      ignoredRouteFiles: ["**/.*"],
      future: {
        v3_fetcherPersist: true,
        v3_relativeSplatPath: true,
        v3_throwAbortReason: true,
        v3_lazyRouteDiscovery: true,
        v3_singleFetch: true,
        v3_routeConfig: true,
      },
    }),
    tsconfigPaths(),
  ],
  build: {
    assetsInlineLimit: 0,
  },
}) satisfies UserConfig;

The vercelPreset() is the crucial addition here. This preset automatically configures Remix to work with Vercel Functions, handling the server-side rendering setup that makes your routes accessible in production.

Step 3: Handle Package Version Conflicts

One major gotcha I encountered was version conflicts between Remix packages and @vercel/remix. If you see peer dependency warnings during installation, you need to ensure all your Remix packages match the version expected by @vercel/remix.

Check what version @vercel/remix expects:

pnpm info @vercel/remix peerDependencies

Then align your Remix packages to match (example versions):

pnpm add @remix-run/dev@2.16.7 @remix-run/node@2.16.7 @remix-run/react@2.16.7 @remix-run/serve@2.16.7

This alignment ensures compatibility between Vercel's integration and your Remix installation.

Step 4: Configure Vercel Build Settings (Optional)

If you're still getting build failures due to peer dependency conflicts, you may need to override Vercel's install command. Create a vercel.json in your project root:

{
  "installCommand": "npm install --legacy-peer-deps"
}

This tells Vercel to ignore peer dependency conflicts during installation. While not ideal, it's sometimes necessary when dealing with version mismatches between the official Vercel integration and the latest Remix releases.

Step 5: Verify Your Build

Test your build locally to ensure everything works:

pnpm run build

You should see output indicating both client and server builds completed successfully, with no errors about routing or server configuration.

Why This Approach Works

The Vercel preset handles several critical configurations automatically:

  • Server-side rendering setup: Configures Remix to work with Vercel's serverless functions
  • Route handling: Ensures all your Remix routes are properly mapped to Vercel's routing system
  • Asset optimization: Configures static asset serving with appropriate caching headers
  • Function deployment: Packages your Remix app as Vercel Functions that can handle dynamic requests

Without this preset, Vercel treats your Remix app as a static site, which explains why direct navigation to routes results in 404 errors.

The Key Gotcha: Build Command Overrides

One important lesson from my experience: if you've previously configured custom build commands in Vercel's dashboard, make sure to remove them. I had overridden the build command to use npm instead of the detected package manager, which caused conflicts with the dependency resolution.

Always let Vercel auto-detect your package manager and use the default build process when possible.

Conclusion

The 404 errors you encounter when deploying Remix apps to Vercel stem from improper server-side rendering configuration. By using the official @vercel/remix package and its Vite preset, you get a zero-configuration setup that properly handles routing in Vercel's serverless environment.

The key steps are installing the official package, adding the preset to your Vite config, and ensuring package version compatibility. With these changes, your Remix routes will work identically in both development and production.

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

Thanks, Matija

0

Comments

Enjoyed this article?
Subscribe to my newsletter for more insights and tutorials.
Matija Žiberna
Matija Žiberna
Full-stack developer, co-founder

I'm Matija Žiberna, a self-taught full-stack developer and co-founder passionate about building products, writing clean code, and figuring out how to turn ideas into businesses. I write about web development with Next.js, lessons from entrepreneurship, and the journey of learning by doing. My goal is to provide value through code—whether it's through tools, content, or real-world software.

You might be interested in