Replit's Static Deployment hosts HTML, CSS, and JavaScript files for free with automatic caching and a .replit.app subdomain. Configure the build command and output directory in the Deployments pane, set up routing for single-page apps, and publish. Static deployments do not support backend code, server-side rendering, or Secrets — they serve files only.
Deploy static websites on Replit with free hosting
Replit offers four deployment types, and Static Deployment is the simplest and cheapest — it is free for hosting with only data transfer charges. Static deployments serve HTML, CSS, and JavaScript files from a CDN with automatic caching and TLS certificates. This is ideal for portfolios, documentation sites, landing pages, and single-page applications built with React, Vue, or vanilla JavaScript. However, static deployments have important limitations: no backend code, no server-side rendering, no Secrets, and a 1 GB size limit. This tutorial covers the full setup, including build commands, routing configuration, and custom domains.
Prerequisites
- A Replit account (any plan — static hosting is free)
- A project with static files (HTML/CSS/JS) or a build-based framework (React, Vite, Vue)
- Understanding of the difference between static files and server-side code
- Familiarity with the .replit configuration file (enable Show hidden files in the filetree menu)
- For custom domains: a registered domain name and access to DNS settings
Step-by-step guide
Verify your project is compatible with static deployment
Verify your project is compatible with static deployment
Static deployments only serve files — they cannot run backend code. Check that your project does not rely on a Node.js or Python server, does not use server-side rendering (SSR), and does not depend on Secrets (environment variables are not available in static deployments). If your project uses React, Vue, or another frontend framework, it must be built into static HTML/CSS/JS files first. Projects built with Replit Agent typically include backends and are NOT compatible with static deployment — use Autoscale or Reserved VM instead.
Expected result: You confirm that your project produces static output (HTML, CSS, JS files) and does not require a running server.
Configure the build command in .replit
Configure the build command in .replit
For framework-based projects (React, Vite, Vue), you need a build command that compiles your source code into static files. Open the .replit file (Show hidden files > .replit) and add the deployment configuration. The build command typically runs your framework's build script, and the output goes to a dist or build directory. For plain HTML/CSS/JS projects without a build step, you can skip this — just point the deployment to your root directory.
1# .replit configuration for static deployment23[deployment]4run = ""5build = "npm run build"6deploymentTarget = "static"78# For Vite projects, output is in 'dist'9# For Create React App, output is in 'build'1011[[ports]]12localPort = 300013externalPort = 80Expected result: The .replit file contains the correct build command and deployment target. Running the build command in Shell produces the output directory.
Test the build locally before deploying
Test the build locally before deploying
Before deploying, run your build command in the Shell to verify it completes without errors and produces the expected output directory. Check that the output directory contains an index.html file at the root — this is required for the deployment to work. Open the output directory in the file tree and verify that all CSS, JavaScript, and asset files are present. Missing files usually indicate a misconfigured build script or incorrect file paths in your source code.
1# Run the build command2npm run build34# Verify the output directory5ls -la dist/67# Check for index.html8cat dist/index.html | head -20910# Check total size (must be under 1 GB)11du -sh dist/Expected result: The build completes without errors, the dist (or build) directory contains index.html and all assets, and the total size is under 1 GB.
Configure routing for single-page applications
Configure routing for single-page applications
Single-page applications (React Router, Vue Router) use client-side routing, which means all URLs should serve the same index.html file. Without proper configuration, refreshing a page like /about returns a 404 because there is no physical about.html file on the server. Replit static deployments support custom routing rules in the .replit file. Add a fallback rule that serves index.html for all paths that do not match a physical file.
1# Add to .replit for SPA routing2[deployment]3run = ""4build = "npm run build"5deploymentTarget = "static"67# Serve index.html for all routes (SPA fallback)8[[deployment.routing]]9path = "/*"10file = "/index.html"Expected result: After deployment, navigating to any route (e.g., /about, /dashboard) correctly loads the SPA instead of showing a 404 error.
Publish the static deployment
Publish the static deployment
Open the Deployments pane from the Tools dock or top navigation. Select Static as the deployment type. Replit shows a summary of your build configuration. Review the settings, then click Publish (or Deploy). The deployment process runs your build command, uploads the output files to Replit's CDN, and assigns a .replit.app subdomain. The first deployment typically takes 30-60 seconds. Subsequent deployments are faster since only changed files are uploaded.
Expected result: Your site is live at https://your-project-name.replit.app with a valid TLS certificate. The Deployments pane shows the URL and deployment status.
Set up a custom domain (optional)
Set up a custom domain (optional)
Static deployments support custom domains on all plans. In the Deployments pane, go to Settings and click Link a domain. Enter your domain name and Replit generates A records and a TXT record for DNS verification. Log into your domain registrar (GoDaddy, Namecheap, Cloudflare, etc.) and add these DNS records. Propagation takes minutes to 48 hours. Replit automatically provisions a TLS certificate once DNS is verified. If using Cloudflare, set the DNS record to DNS-only mode (gray cloud) — proxied mode blocks certificate auto-renewal.
1# DNS records to add at your registrar2# (Replit provides exact values in the Deployments pane)34# A Record5Type: A6Name: @ (or your subdomain)7Value: [IP address from Replit]89# TXT Record (for verification)10Type: TXT11Name: @ (or your subdomain)12Value: [verification string from Replit]Expected result: Your custom domain resolves to your Replit static site with a valid TLS certificate. Both the .replit.app URL and custom domain work.
Understand static deployment limitations
Understand static deployment limitations
Static deployments have specific constraints you must understand before choosing this deployment type. There is no server-side code execution, so you cannot use Node.js, Python, or any backend framework. Secrets (environment variables) are not available — if your frontend needs API keys, you must either hardcode them (only for public keys) or use a separate backend. The maximum app size is 1 GB. The filesystem is not persistent and resets on each deployment. There is no WebSocket support. If any of these limitations affect your project, use Autoscale or Reserved VM deployment instead.
Expected result: You understand the boundaries of static deployment and can decide whether it is the right choice for your project.
Complete working example
1# .replit — Complete configuration for static site deployment2# This file controls how Replit builds and deploys your project.3# Show hidden files in the filetree menu to see this file.45# Development run command (used when clicking Run in workspace)6run = "npm run dev"78# Entry point for the editor9entrypoint = "src/main.jsx"1011# Hide unnecessary files from the file tree12hidden = [".config", "node_modules", "package-lock.json"]1314# Module configuration15modules = ["nodejs-20:v8-20230920-bd784b9"]1617# Nix packages18[nix]19channel = "stable-24_05"20packages = ["nodejs_20"]2122# Development port mapping23[[ports]]24localPort = 517325externalPort = 802627# Deployment configuration for static hosting28[deployment]29run = ""30build = "npm run build"31deploymentTarget = "static"3233# SPA routing — serve index.html for all routes34[[deployment.routing]]35path = "/*"36file = "/index.html"3738# Cache static assets for better performance39[[deployment.routing]]40path = "/assets/*"41headers = { "Cache-Control" = "public, max-age=31536000, immutable" }Common mistakes when deploying static sites on Replit
Why it's a problem: Deploying an Agent-built app (which includes a backend) as a static site, causing 404 errors or missing functionality
How to avoid: Agent-built apps almost always need a server. Use Autoscale Deployment for apps with backends, APIs, or database connections.
Why it's a problem: Expecting environment variables (Secrets) to work in static deployments — they are not available
How to avoid: Static deployments only serve files. Use build-time environment variables (VITE_ prefix for Vite) that are baked into the bundle, or use a separate backend for sensitive operations.
Why it's a problem: Not configuring SPA routing, causing 404 errors when users refresh on routes like /about or /dashboard
How to avoid: Add [[deployment.routing]] with path = '/*' and file = '/index.html' to the .replit file to serve index.html for all routes.
Why it's a problem: Adding AAAA DNS records alongside A records for a custom domain, causing intermittent connection failures
How to avoid: Remove all AAAA records for the domain. Replit only supports A records. Having both causes DNS resolution conflicts.
Why it's a problem: Exceeding the 1 GB size limit for static deployments, causing silent deployment failures with no clear error message
How to avoid: Run du -sh dist/ in the Shell before deploying. If over 1 GB, compress images, enable code splitting, and remove unused dependencies.
Best practices
- Always test the build command in the Shell before deploying — fix build errors locally before triggering a deployment
- Add SPA routing configuration for any React, Vue, or Angular app that uses client-side routing to prevent 404 errors on page refresh
- Keep static deployments under 1 GB total size — use image compression and code splitting to reduce bundle size
- Set long cache headers for assets in the /assets or /static directory since frameworks add content hashes to filenames
- Never put private API keys in static site code — they are visible to anyone who views the page source
- Use Autoscale or Reserved VM deployment if your project needs a backend, SSR, or environment variables
- If using Cloudflare, set DNS records to DNS-only mode (gray cloud) to allow Replit to provision TLS certificates
- Monitor data transfer usage under your plan — static sites can generate unexpected transfer costs with high traffic
Still stuck?
Copy one of these prompts to get a personalized, step-by-step explanation.
I have a [React/Vue/vanilla JS] project on Replit that I want to deploy as a static site. My build command is [command] and the output goes to [directory]. Help me write the .replit deployment configuration including SPA routing.
Deploy this project as a static site. Make sure the build command works correctly, the output directory has an index.html file, and the .replit file has the correct deployment configuration including SPA routing fallback. Check that the total build output is under 1 GB.
Frequently asked questions
Yes, hosting is free. You only pay for data transfer beyond your plan's allocation (Core includes 100 GiB outbound). Excess transfer costs $0.10 per GiB.
No. Static deployments only serve files. If your app needs a backend, server-side rendering, or database access, use Autoscale or Reserved VM deployment instead.
You need SPA routing configured. Add [[deployment.routing]] with path = '/*' and file = '/index.html' to your .replit file so all routes serve the same index.html.
Static deployments support up to 1 GB of total files. Autoscale and Reserved VM deployments support up to 8 GB.
No. Secrets are not available in static deployments. For build-time variables, use the VITE_ prefix (for Vite projects) which gets baked into the JavaScript bundle during build. Never include private API keys this way — they are visible in the browser.
In the Deployments pane, go to Settings and click Link a domain. Add the A records and TXT record Replit provides to your domain registrar's DNS settings. TLS certificates are provisioned automatically after DNS verification.
Yes. RapidDev's engineering team helps with build pipeline optimization, custom domain setup, SPA routing issues, and migration from static to Autoscale deployments when projects outgrow static hosting.
No. The filesystem resets every time you publish a new deployment. Do not rely on writing files to disk at runtime — use external storage or a database for persistent data, which requires a different deployment type.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation