This guide explains how to deploy a basic Remix site to Sevalla.
Remix is a full-stack, server-side web framework built on modern web standards and designed for fast, resilient, and highly interactive applications. Its core philosophy is to embrace the browser platform, using web APIs wherever possible, and to prioritize user experience through advanced routing, progressive enhancement, and optimized data loading patterns.Remix can only be used on Application Hosting; it cannot be deployed as a static site.We recommend the following best practices to get the best performance when using Remix on Sevalla:
Use Remix loaders for efficient, server-side data fetching.
Apply appropriate Cache-Control headers in loader responses to maximize CDN performance.
Take advantage of Remix’s built-in prefetching to speed up client-side navigation.
Use resource routes for API endpoints to simplify data access and caching.
You can customize the Nixpacks build process by defining a nixpacks.toml file and using Nixpacks-specific environment variables. This allows you to fine-tune how dependencies are installed, how your application is built, and which runtime settings are applied.The following is an example nixpacks.toml configuration:
Nixpacks will automatically detect your project’s lock file and select the appropriate package manager during deployment.Additionally, you can specify the Node.js version used during the build by setting the NIXPACKS_NODE_VERSIONenvironment variable.
If you’re using Buildpacks, you cannot modify the underlying build phases directly or control dependencies. You must rely on the runtime environment that Buildpacks detects.You can influence the build process by adjusting the build script in your package.json. Buildpacks will run whatever command you specify under the build script. For example, the standard command used to compile a Remix application is:
Copy
Ask AI
"build": "remix build"
You can also add additional logic before the build runs, for example:
Sevalla provides a premium, Cloudflare-powered CDN for Application Hosting at no additional cost. To get the most out of Sevalla’s CDN when deploying your Remix application, we recommend the following best practices:
Enable the CDN for all production applications to ensure global, low-latency delivery.
Set appropriate Cache-Control headers on API routes to ensure proper caching behavior.
Purge CDN cache after critical deployments to ensure users receive updated content.
Rely on Remix’s versioned assets in the build/ directory, which are safe to cache indefinitely.
Store static files in the public/ directory, allowing the CDN to serve them efficiently.
Edge caching stores your Sevalla site cache on Cloudflare’s 260+ global data centers, delivering responses from the location nearest to each visitor for faster performance. To maximize the benefits of Sevalla’s Edge Caching for your Remix application, we recommend the following best practices:
Set appropriate Cache-Control headers in loaders to control caching behavior.
Combine edge caching with the CDN for a complete caching strategy.
Use Remix’s useFetcher for client-side revalidation.
With Sevalla’s Cloudflare integration,Cache-Controlheaders are respected at the edge, giving you precise control over how content is cached and served globally. The following are some common directives you can use in your Remix application:
public, s-maxage=3600 - Caches the response on the CDN for 1 hour, improving performance for frequently accessed content.
public, max-age=31536000, immutable - Ideal for versioned static assets, allowing them to be cached for up to 1 year with no revalidation.
private - Prevents CDN caching and ensures the response is only cached by the end user’s browser, for personalized or sensitive data.
Sevalla does not yet support the stale-while-revalidate Cache-Control directive. To prevent unexpected caching behavior, we recommend not using this directive in your API or asset caching settings.
Remix provides automatic graceful shutdown when using remix-serve, but you can add custom cleanup logic, such as closing database connections, by handling SIGTERM and SIGINT yourself. The example below demonstrates how to shut down a PostgreSQL connection pool during termination:
Copy
Ask AI
// app/lib/db.server.tsimport { Pool } from "pg";export const pool = new Pool({ connectionString: process.env.DATABASE_URL, max: 20, idleTimeoutMillis: 30000,});// Graceful pool shutdownconst gracefulPoolShutdown = async () => { console.log("Closing database pool..."); await pool.end(); console.log("Database pool closed");};process.on("SIGTERM", async () => { await gracefulPoolShutdown(); process.exit(0);});process.on("SIGINT", async () => { await gracefulPoolShutdown(); process.exit(0);});
This pattern ensures active connections are closed cleanly before your application stops, preventing dropped queries or pool corruption.
Sevalla fully supports multi-tenancy. You can build multi-tenant Remix applications using wildcard domains, allowing you to efficiently and securely serve multiple tenants from separate subdomains. Use the following best practices for multi-tenancy on Sevalla with your Remix application:
Use wildcard domains to serve subdomain-based tenants (e.g., tenant1.app.com).
Add custom domains individually for tenants who have their own domains.
Cache tenant data to reduce database queries and improve performance.
Validate tenant existence before rendering pages to prevent errors or unauthorized access.
Isolate tenant data in the database using separate schemas or a tenant_id column.
Leverage free SSL certificates, which are automatically provided for both wildcard and custom domains.