Static File Hosting
Deploy static websites and assets using Freestyle's native static file hosting
Freestyle's native static file hosting lets you deploy HTML, CSS, JavaScript, images, and other assets directly without needing a server. Perfect for static sites, documentation, landing pages, and modern framework outputs.
Overview
Freestyle provides built-in static file hosting options that serve your files efficiently. You can:
- Deploy pure static sites without any server code
- Serve public assets at your domain root
- Serve framework-specific static directories with custom paths
- Mix static files with dynamic server routes
Sign up at dash.freestyle.sh, create an api key, and configure it in your environment.
FREESTYLE_API_KEY=your-api-keynpm i freestyleQuick Start: Pure Static Site
For a completely static site with no server needed:
import { freestyle } from "freestyle";
const { deployment, domains } = await freestyle.serverless.deployments.create({
repo: "https://github.com/your-username/your-static-site",
domains: ["my-site.style.dev"],
staticOnly: true,
publicDir: "public", // Your static files directory
});
console.log("Deployed to:", domains[0]);That's it! Freestyle serves all files from your public directory directly.
Static File Hosting
Freestyle offers multiple options for serving static files. Choose the approach that matches your site structure.
Public Directory: Root-Level Files
Serve files from a directory at your domain root:
const { deployment, domains } = await freestyle.serverless.deployments.create({
repo: "https://github.com/your-username/your-site",
domains: ["my-site.style.dev"],
staticOnly: true,
publicDir: "public", // All files served at root
});Files are served without any path prefix:
public/favicon.ico→/favicon.icopublic/robots.txt→/robots.txtpublic/index.html→/index.htmlpublic/about/index.html→/about/index.html
publicDir is commonly used with Next.js, Hugo, Jekyll, and other frameworks that have a public/ directory for static assets.
Static Directory with Custom Path
Serve a specific directory at a specific URL path prefix:
const { deployment, domains } = await freestyle.serverless.deployments.create({
repo: "https://github.com/your-username/your-site",
domains: ["my-site.style.dev"],
staticOnly: true,
staticDir: ".next/static",
staticPathPrefix: "/_next/static", // Files at this path
});Files are served at the specified prefix:
.next/static/chunk.js→/_next/static/chunk.js.next/static/style.css→/_next/static/style.css
Use staticDir with staticPathPrefix for framework-specific asset directories like Next.js's _next/static or Nuxt's .nuxt/dist/client.
Prerendered HTML
Serve prerendered HTML files that map to URL paths:
const { deployment, domains } = await freestyle.serverless.deployments.create({
repo: "https://github.com/your-username/your-site",
domains: ["my-site.style.dev"],
staticOnly: true,
prerenderedDir: "out", // Hugo, Jekyll, Static export output
});When a request comes in, Freestyle looks for:
out/about.htmlfor/aboutout/index.htmlfor/out/blog/post.htmlfor/blog/post
Perfect for static site generators like Hugo, Jekyll, Eleventy, or Next.js static exports.
Advanced Configuration
Clean URLs
Remove .html extensions from filenames:
const { deployment, domains } = await freestyle.serverless.deployments.create({
repo: "https://github.com/your-username/your-site",
domains: ["my-site.style.dev"],
staticOnly: true,
publicDir: "public",
cleanUrls: true, // /about.html becomes /about
});When cleanUrls: true:
- Visiting
/about.htmlredirects to/about /aboutservespublic/about.html- Perfect for HTML-only sites
Trailing Slashes
Control whether trailing slashes are required:
const { deployment, domains } = await freestyle.serverless.deployments.create({
repo: "https://github.com/your-username/your-site",
domains: ["my-site.style.dev"],
staticOnly: true,
publicDir: "public",
trailingSlash: true, // /about/ required, /about redirects
});Custom Headers
Set HTTP headers for caching, security, etc.:
const { deployment, domains } = await freestyle.serverless.deployments.create({
repo: "https://github.com/your-username/your-site",
domains: ["my-site.style.dev"],
staticOnly: true,
publicDir: "public",
headers: [
{
source: "^/assets/.*$",
headers: [
{ key: "Cache-Control", value: "max-age=31536000, immutable" },
],
},
{
source: ".*",
headers: [{ key: "X-Content-Type-Options", value: "nosniff" }],
},
],
});Redirects
Set up URL redirects:
const { deployment, domains } = await freestyle.serverless.deployments.create({
repo: "https://github.com/your-username/your-site",
domains: ["my-site.style.dev"],
staticOnly: true,
publicDir: "public",
redirects: [
{
source: "^/old-page$",
destination: "/new-page",
permanent: true, // 308 permanent redirect
},
{
source: "^/blog/(.*)$",
destination: "/posts/$1",
permanent: false, // 307 temporary redirect
},
],
});Rewrites
Rewrite URLs internally without changing the browser URL:
const { deployment, domains } = await freestyle.serverless.deployments.create({
repo: "https://github.com/your-username/your-site",
domains: ["my-site.style.dev"],
staticOnly: true,
publicDir: "public",
rewrites: [
{
source: "/api/(.*)",
destination: "https://api.example.com/$1",
},
{
source: "/docs/(.*)",
destination: "/documentation/$1",
},
],
});Common Site Generators
Next.js Static Export
const { deployment, domains } = await freestyle.serverless.deployments.create({
repo: "https://github.com/your-username/nextjs-site",
domains: ["my-site.style.dev"],
staticOnly: true,
build: {
command: "npm run build",
},
publicDir: "out", // Next.js static export output
});Hugo
const { deployment, domains } = await freestyle.serverless.deployments.create({
repo: "https://github.com/your-username/hugo-site",
domains: ["my-site.style.dev"],
staticOnly: true,
build: {
command: "hugo",
},
publicDir: "public", // Hugo output directory
cleanUrls: true,
});Jekyll
const { deployment, domains } = await freestyle.serverless.deployments.create({
repo: "https://github.com/your-username/jekyll-site",
domains: ["my-site.style.dev"],
staticOnly: true,
build: {
command: "jekyll build",
},
publicDir: "_site", // Jekyll output directory
});Eleventy (11ty)
const { deployment, domains } = await freestyle.serverless.deployments.create({
repo: "https://github.com/your-username/eleventy-site",
domains: ["my-site.style.dev"],
staticOnly: true,
build: {
command: "npx eleventy",
},
publicDir: "_site", // Eleventy output directory
});Deploying with Git
Simply push your static site to a Git repository and deploy:
import { freestyle } from "freestyle";
const { deployment, domains } = await freestyle.serverless.deployments.create({
repo: "https://github.com/your-username/my-static-site",
branch: "main", // Optional: specify branch
domains: ["my-site.style.dev"],
staticOnly: true,
publicDir: "public", // Your output directory
});
console.log("Deployed to:", domains[0]);