Skip to main content

How to Deploy a Static Website With Free Forms & Analytics

Published: •Last updated: Static Website Hosting
static website hostinghtml formswebsite analyticscustom domainsdeployment
Illustration: a zipped static site uploaded to a live website with a contact form and an analytics chart

To deploy a static website with free forms and analytics, zip your built site so index.html sits at the top of the ZIP, create a website in Statpio and drop the ZIP on the Deployments page, and it goes live on a free yourname.onstatpio.com address with SSL. Any HTML form with method="POST" and no action attribute is then captured automatically, and a small cookieless analytics script is added to every page, so there is nothing else to install. The Free Forever plan includes 250 form submissions per website a month; connecting your own domain needs Solo Pro.

Disclosure: this guide is published by Statpio, one of the tools compared. We link every competitor fact to its official source.

What does the free plan include, and what needs Solo Pro?

Free ForeverSolo Pro
PriceFree$9/month or $89/year
Active projects15
Web addressFree *.onstatpio.com subdomain with SSLSubdomain plus 5 custom domains with SSL included (extra domains $0.50/month each)
Form submissions per website, per month25010,000
AnalyticsVisitors, sources, pages, countries, devices and browsers; 30 daysAdds UTM campaigns, goals, funnels, live visitor view; 90 days
Ways to deployZIP uploadZIP upload and GitHub push-to-deploy
Storage / largest upload250 MB / 25 MB5 GB / 50 MB
Deployments per day25200
BandwidthUnmeteredUnmetered
Statpio badge on the siteYesNo

Source: Statpio pricing page, October 2026.

Step 1: Build and zip your site

  1. Upload finished files, not source code. A hand-written HTML site is already finished; otherwise run your build (often npm run build) and use the output folder, for example dist for Vite or out for a Next.js static export (output: 'export').
  2. Open that folder, select everything inside it and compress the selection: Compress on macOS, or Send to → Compressed (zipped) folder on Windows (on Windows 11 it's under Show more options). This keeps index.html at the top level of the ZIP.
  3. Check that the ZIP is under your plan's upload limit (25 MB on Free Forever).

If index.html is missing or nested too deep, the upload stops with "ZIP file must contain an index.html file in the root directory."

Step 2: Create a website and upload the ZIP

  1. Create a free Statpio account and verify your email address; uploads stay locked until you do.
  2. On the Websites page, click New Website, type a name such as my-portfolio and click Create. The form shows the address your site will get, for example my-portfolio.onstatpio.com.
  3. Open Deployments in the project menu and leave Deployment Type on Static Site (pre-built HTML, CSS and JavaScript).
  4. Drag your ZIP onto Drop your website ZIP here. When the upload finishes, the site is live at that address.

Every upload becomes a new deployment, and you can roll back instantly to an earlier one (Free Forever keeps the last 5). If you upload a React or Vite app with client-side routing, Statpio detects it and switches on SPA Mode (under Settings), so routes such as /about don't 404 on refresh. If your site is made of separate HTML pages and SPA Mode was switched on, turn it off, so a missing URL returns a 404 instead of your home page.

Built it with an AI tool? Bolt's Vite projects and older React + Vite Lovable apps build to static files and deploy this way. Lovable apps created since 13 May 2026 use TanStack Start, which needs a server, so they can't be hosted as-is. See how to deploy AI-generated websites from Lovable, Bolt and v0.

Step 3: How do I add a contact form without a backend?

Use a plain HTML form with method="POST" and no action attribute. On your live Statpio site, every form like this is captured automatically, with no endpoint, API key or script to add.

<form method="POST">
  <label for="name">Name</label>
  <input id="name" name="name" type="text" required>

  <label for="email">Email</label>
  <input id="email" name="email" type="email" required>

  <label for="message">Message</label>
  <textarea id="message" name="message" rows="5" required></textarea>

  <button type="submit">Send message</button>
</form>

Three details make it work:

  • method="POST" is required. A form without it submits with GET, and Statpio doesn't capture it.
  • Leave out action. If an old form points at another service, such as a Formspree URL, remove the attribute, or submissions keep going there.
  • Give every field a name. Browsers only send fields that have one (MDN: an input with no name isn't submitted), and the name is how the field appears in your leads.

What does Statpio add to the form?

  • A visible Cloudflare Turnstile check above the submit button. Visitors complete it before the form sends, and it can't be switched off.
  • A hidden honeypot field (__statpio_hp) that catches simple bots.
  • Sending without a page reload: the visitor sees "Form submitted successfully!" and the form clears.

So don't add your own versions. A JavaScript submit handler (fetch() with preventDefault()) conflicts with Statpio's handler and breaks the CAPTCHA, and a _gotcha or other honeypot field is simply stored as an ordinary field. If a JavaScript framework renders your form, keep it a real <form method="POST"> with no submit handler of your own, and send a test from the live site.

File uploads work too: add enctype="multipart/form-data" to the form tag and a field such as <input type="file" name="attachment">.

Where do submissions go?

Submissions appear under Forms & Leads in the project dashboard. To hear about new ones, turn on browser notifications on your computer or phone. No HTML to hand? Build a form under Forms & Leads → Forms instead, from a ready-made contact, quote or booking form.

Free Forever includes 250 submissions per website a month and Solo Pro includes 10,000. You get a warning at 80% and when a website reaches its limit. After that, it keeps up to the same number again, locked until you move to a plan with a higher limit; past that, new submissions are turned away with an error message until the next month starts.

Test on your live URL: capture happens on Statpio's servers, so a page opened from your computer records nothing. Comparing dedicated form services instead? See our Formspree alternatives for static sites.

Step 4: How do I see visitor analytics without Google Analytics?

There is nothing to install. Statpio adds a lightweight (about 3 KB compressed) first-party script to every HTML page it serves, and pageviews start showing under Analytics once people visit.

  • Every plan: visitors, pageviews, visit duration, channels and referrers, top pages, countries, devices, browsers and operating systems, with 30 days of history on Free Forever.
  • Solo Pro and up: adds UTM campaigns, goals, funnels, Core Web Vitals, the live visitor view and 90 days of history.

Bounce rate and visit duration are rough guides: a bounce is a visit with one pageview, and duration runs from a visit's first to its last recorded activity. In single-page apps, client-side route changes count as pageviews.

Is it privacy-friendly, and do I need consent?

The script sets no cookies and loads no third-party trackers or ad networks. It doesn't store a visitor ID in the browser: unique visitors are counted with a hash made on the server, with a salt that changes every day, and the script keeps only a visit ID in sessionStorage for the open tab. Cookieless doesn't automatically mean no consent is needed: EU guidance on the ePrivacy rules covers information kept in local storage as well as cookies (EDPB Guidelines 2/2023). Check whether your jurisdiction requires visitor consent. Like any JavaScript analytics, the script can also be blocked by some content blockers.

Step 5 (optional): How do I connect my own domain?

Custom domains are on Solo Pro and up, with 5 included. On Free Forever, the Custom Domains page shows an upgrade prompt instead. After you upgrade:

  1. Open Custom Domains, keep the www. Domain mode (recommended), type yourdomain.com and click Connect Domain. Statpio sets it up as www.yourdomain.com. Choose Custom Subdomain instead for an address like blog.yourdomain.com.
  2. At your DNS provider, add the two CNAME records the dashboard shows (see the table below). Copy the values from the dashboard rather than typing them.
  3. Wait for the domain's status to change from Pending DNS to Active; the refresh button checks again. SSL is issued automatically once the validation record is found.
  4. At your registrar, forward the root domain (yourdomain.com) to https://www.yourdomain.com with a permanent (301) redirect, because the root is served through www. The dashboard shows how to do this at GoDaddy, Cloudflare, Namecheap and Hostinger.
RecordTypeName / HostPoints to
WebsiteCNAMEwwwcname.onstatpio.com
SSL validationCNAME_acme-challenge.wwwThe value shown in the dashboard, which looks like www.yourdomain.com.<id>.dcv.cloudflare.com

For a custom subdomain such as blog, the names are blog and _acme-challenge.blog. If a domain stays on Pending DNS, the dashboard links to Google's public DNS so you can see whether each record is visible yet.

Can I deploy from GitHub instead of uploading a ZIP?

Yes, on Solo Pro and up. Connect a repository and branch under Integrations, and each push to that branch deploys the site. On every plan you can also publish from Claude, ChatGPT or Cursor with the Statpio connector, from the command line (npx statpio deploy ./dist) or through the deploy API with a website API key.

What usually goes wrong?

ProblemLikely causeFix
Upload fails with "ZIP file must contain an index.html file in the root directory."index.html is missing, or nested more than one folder deep in the ZIPZip the contents of your build folder, not a folder above it
Form submits, but nothing appears in Forms & LeadsNo method="POST", an action that points elsewhere, or a test from a local fileAdd method="POST", remove action, test on the live URL
Submissions fail or the CAPTCHA breaksYour own JavaScript submit handlerRemove it and let Statpio send the form
Pages return 404 on refresh in a React or Vite appSPA Mode is offTurn on SPA Mode in Settings

How does this compare with Netlify, Cloudflare Pages and GitHub Pages?

Statpio isn't the only host with built-in forms or analytics. As of October 2026:

HostBuilt-in form captureBuilt-in analyticsCustom domain on the free plan
StatpioYes, automatic for POST forms, or built without code; 250 per website a month on Free ForeverYes, cookieless script; basic on Free ForeverNo, needs Solo Pro
NetlifyYes, Netlify Forms: free and unlimited on credit-based plans; you enable form detection and add data-netlify="true"Web analytics on every credit-based plan; Free shows the current and past dayYes
Cloudflare PagesNo built-in form storage; you write a Pages Function (Cloudflare's Static Forms plugin helps) or use a form serviceFree Cloudflare Web Analytics with one-click setupYes, up to 100 per project
GitHub PagesNoNoYes, with HTTPS

Sources (checked October 2026): Netlify Forms, credits, plans and pricing; Cloudflare Pages Static Forms plugin, Web Analytics and limits; GitHub Pages overview and HTTPS.

Choose Netlify if you want built-in forms without a monthly cap, but note that its Free plan runs on 300 credits a month and pauses your sites when they run out. Choose Cloudflare Pages for free hosting on your own domain with analytics, if you can handle forms yourself. GitHub Pages is free for public repositories, but GitHub's usage limits say it isn't meant as free hosting for an online business. Statpio fits when you want forms, spam protection and analytics on a plain ZIP upload with nothing to set up.

When is static hosting the wrong choice?

Statpio hosts static output only: Node servers, server-side rendering, API routes and server actions don't run, and there is no built-in database or backend. If your app needs those, use a host that runs server code, such as Vercel for a full Next.js app. A Next.js site that builds as a static export still works on Statpio.

A folder with an index.html is all you need to start: deploy it on the free plan and add your form. When you want your own domain or GitHub deploys, compare the plans on the pricing page.

Frequently asked questions

Can I host a static website for free on Statpio?

Yes. The Free Forever plan gives you 1 active project on a free *.onstatpio.com subdomain with SSL, ZIP upload, basic analytics and 250 form submissions per website a month, with a small Statpio badge on the site. Custom domains and GitHub push-to-deploy need Solo Pro ($9 a month or $89 a year).

How do I add a contact form to a static HTML site without a backend?

On Statpio, write a normal <form method="POST"> with no action attribute and a name on every field, then deploy. Statpio captures each submission, adds a visible Cloudflare Turnstile check and a hidden honeypot itself, and lists the leads under Forms & Leads. Don't add your own fetch() submit handler or a _gotcha field.

How do I hear about new form submissions?

Turn on browser notifications on your computer or phone, and Statpio alerts you to each new submission, even with the tab closed. Every submission is also listed in the dashboard under Forms & Leads.

Do I need Google Analytics for a static site?

Not for most traffic questions. Statpio adds a lightweight (about 3 KB compressed) first-party, cookieless script to every page: every plan shows visitors, pageviews, sources, top pages, countries and devices, and Solo Pro adds UTM campaigns, goals, funnels and the live visitor view. The script keeps a visit ID in sessionStorage, so check whether your jurisdiction requires visitor consent.

What DNS records do I need to connect my own domain?

Two CNAME records: www pointing to cname.onstatpio.com, and _acme-challenge.www pointing to the validation value shown in the Statpio dashboard (it ends in .dcv.cloudflare.com). SSL is issued automatically once the validation record is found. Forward the root domain to www at your registrar. Custom domains need Solo Pro or higher.

Can I deploy a React, Vite or Next.js site this way?

Yes, if it builds to static files. Upload the build output (dist for Vite, out for a Next.js static export with output: 'export'). Turn on SPA Mode for client-side routing; Statpio switches it on automatically when it detects a single-page app. Server-side code such as SSR, API routes and server actions does not run on Statpio.

Keep reading