LogoFreestyle
Guides

Deploying Vite

How to deploy Vite websites on Freestyle

Vite is a modern build tool that provides fast development and optimized production builds. This guide shows you how to deploy Vite applications to Freestyle.

Prerequisites

  • A Vite application (create one with npm create vite@latest)
  • Freestyle API key from the Freestyle Dashboard
  • The Freestyle SDK installed: npm install freestyle

Setup

If you're starting fresh, create a new Vite project:

npm create vite@latest

Follow the prompts to select your framework (React, Vue, Svelte, etc.) and install dependencies:

cd my-vite-app
npm install

Deployment Methods

There are two primary ways to deploy Vite apps to Freestyle:

The simplest approach is to deploy directly from your Git repository. Freestyle will automatically detect and build your Vite app.

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-vite-app",
      // branch: "main",        // Optional: specify branch
      // rootPath: "./web",     // Optional: for monorepos

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

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

deploy();

Freestyle automatically detects Vite projects and runs the build command. The built output is served from the dist directory by default.

Method 2: Deploy from Local Files

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

Step 1: Build Your Vite App

npm run build

This creates a production build in the dist folder with optimized static assets.

Step 2: Create a Server Entrypoint

Freestyle requires a server entrypoint to serve your static files. Install Hono:

npm install hono

Create a server file:

main.ts
import { Hono } from "hono";
import { serveStatic } from "hono/deno";

const app = new Hono();

// Serve static files from dist
app.use("*", serveStatic({ root: "./dist" }));

// Fallback to index.html for client-side routing (SPA)
app.get("*", serveStatic({ path: "./dist/index.html" }));

Deno.serve(app.fetch);

The fallback to index.html is essential for SPAs with client-side routing (React Router, Vue Router, etc.).

Step 3: Deploy Using the SDK

Use the readFiles utility to deploy your built app:

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

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

  const { deployment, domains } = await freestyle.serverless.deployments.create(
    {
      files,
      entrypointPath: "main.ts", // Your server entrypoint
      domains: ["my-vite-app.style.dev"],
    },
  );

  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

Vite exposes environment variables prefixed with VITE_ to your client code. Set them during deployment:

await freestyle.serverless.deployments.create({
  repo: "https://github.com/your-username/your-vite-app",
  build: true,
  domains: ["app.style.dev"],
  envVars: {
    VITE_API_URL: "https://api.example.com",
    VITE_APP_TITLE: "My App",
  },
});

Only environment variables prefixed with VITE_ are exposed to your client-side code. Server-side variables (for your entrypoint) don't need this prefix.

Custom Build Output Directory

If your Vite config uses a custom output directory:

vite.config.ts
export default {
  build: {
    outDir: "build", // Custom output directory
  },
};

Update your deployment configuration:

await freestyle.serverless.deployments.create({
  repo: "https://github.com/your-username/your-vite-app",
  build: {
    command: "npm run build",
    outDir: "build", // Match your Vite config
  },
  domains: ["app.style.dev"],
});

Asset Optimization

Vite already optimizes assets during build. For additional optimization, use deployment headers:

await freestyle.serverless.deployments.create({
  repo: "https://github.com/your-username/your-vite-app",
  build: true,
  domains: ["app.style.dev"],
  headers: [
    {
      source: "^/assets/.*$", // Match all files in /assets
      headers: [{ key: "Cache-Control", value: "max-age=31536000, immutable" }],
    },
  ],
});

Base Path Configuration

If your app is deployed to a subdirectory, configure Vite's base:

vite.config.ts
export default {
  base: "/my-app/",
};

Static-Only Mode

For pure static Vite apps without a custom server:

await freestyle.serverless.deployments.create({
  repo: "https://github.com/your-username/your-vite-app",
  build: true,
  domains: ["app.style.dev"],
  staticOnly: true,
  publicDir: "dist",
});

Server-Side Rendering (SSR)

Vite supports SSR with frameworks like Vue and React. For SSR deployments:

Step 1: Configure Vite for SSR

Follow your framework's SSR guide:

Step 2: Deploy with Custom Entrypoint

await freestyle.serverless.deployments.create({
  repo: "https://github.com/your-username/your-vite-ssr-app",
  build: {
    command: "npm run build:ssr", // Your SSR build command
  },
  entrypointPath: "server.js", // Your SSR server entrypoint
  domains: ["app.style.dev"],
});

Monorepo Setup

For Vite apps in a monorepo, specify the rootPath:

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

Framework-Specific Guides

React + Vite

Vite's React template works out of the box:

npm create vite@latest my-app -- --template react

Deploy with automatic detection:

await freestyle.serverless.deployments.create({
  repo: "https://github.com/your-username/react-vite-app",
  build: true,
  domains: ["app.style.dev"],
});

Vue + Vite + Freestyle

Vue apps follow the same pattern:

npm create vite@latest my-app -- --template vue

Svelte + Vite + Freestyle

Svelte works seamlessly:

npm create vite@latest my-app -- --template svelte

Troubleshooting

Build Fails

If automatic framework detection doesn't work, specify the build command manually:

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

Remember that Freestyle needs a server to run — static files without configuration will not work as a web server.

404 on Routes

Make sure your server has a fallback to index.html:

main.ts
// This line is essential for SPAs
app.get("*", serveStatic({ path: "./dist/index.html" }));

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.