Choosing the right static website hosting platform can save you hundreds of dollars a year while keeping your site fast, secure, and easy to maintain. In 2026, the free tier options have matured significantly, and platforms like GitHub Pages and Cloudflare Pages offer production-ready infrastructure at zero cost. But there is one challenge most tutorials skip: how do you handle contact forms on a static site when there is no server to process them? This guide walks you through the full setup process, from picking a platform to wiring up a working contact form, with concrete examples and the real limitations you need to know before you commit to a platform.
Content Table
Key Takeaways:
- GitHub Pages and Cloudflare Pages both offer genuinely free static web hosting with custom domain support.
- Cloudflare Pages is faster globally due to its CDN edge network; GitHub Pages is simpler for developers already using GitHub.
- Static sites cannot process forms natively - you need a third-party form service to collect submissions and deliver them to your inbox.
- Using a dedicated form backend like Sendform lets you add a fully functional contact form without writing server-side code.
Why Free Static Hosting Is Worth Your Attention
A static website serves pre-built HTML, CSS, and JavaScript files directly to the browser. There is no PHP, no Node.js runtime, and no database query on every page load. That simplicity is exactly why free static page hosting is so reliable: there is nothing to crash, patch, or scale.
For small businesses, portfolios, SaaS landing pages, and documentation sites, static hosting ticks every box:
- Speed: Files are served from a CDN edge node, often in under 100ms globally.
- Security: No server-side runtime means a drastically smaller attack surface.
- Cost: Both GitHub Pages and Cloudflare Pages are free for public and many private projects.
- Simplicity: Push code to a repository, and the site deploys automatically.
The one genuine constraint is dynamic functionality. Anything that requires server-side logic, such as user authentication, a shopping cart, or form processing, needs an external service. Keep that in mind as we go through the setup steps.
Platform Comparison: GitHub Pages vs Cloudflare Pages
| Feature | GitHub Pages | Cloudflare Pages |
|---|---|---|
| Free tier | Yes (public repos always free) | Yes (unlimited sites) |
| Custom domain | Yes | Yes |
| HTTPS | Auto via Let's Encrypt | Auto via Cloudflare SSL |
| Build pipeline | GitHub Actions (manual config) | Built-in CI/CD |
| Global CDN | Limited (US-centric) | 300+ edge locations |
| Bandwidth limit | Soft limit ~100GB/month | Unlimited |
| Private repo support | Requires GitHub Pro | Yes, free |
Bottom line: If your audience is global and you want the fastest possible load times, Cloudflare Pages wins. If your team already lives in GitHub and you want the simplest possible setup, GitHub Pages is perfectly fine.
Step-by-Step: Deploy on GitHub Pages
This example assumes you have a simple HTML/CSS site ready to publish. If you are using a static site generator like Hugo or Jekyll, the process is nearly identical.
-
Create a GitHub repository. Go to github.com/new and create a public repository. Name it
your-username.github.ioif you want it to serve at the root domain, or any name if you want it at a subdirectory path. -
Push your site files. From your local project folder, run:
git init git remote add origin https://github.com/your-username/your-repo.git git add . git commit -m "Initial deploy" git push -u origin main -
Enable GitHub Pages. In the repository, go to Settings > Pages. Under "Source", select the
mainbranch and the/rootfolder (or/docsif your build output goes there). Click Save. -
Wait for deployment. GitHub will build and deploy within 1-3 minutes. You will see the live URL (e.g.,
https://your-username.github.io) appear in the Pages settings panel. -
Connect a custom domain (optional). Add a
CNAMEfile to your repository root containing your domain name (e.g.,www.yoursite.com). Then update your DNS provider to point a CNAME record atyour-username.github.io. GitHub will provision an SSL certificate automatically within a few minutes.
Step-by-Step: Deploy on Cloudflare Pages
- Sign up or log in to Cloudflare. Visit pages.cloudflare.com and connect your GitHub or GitLab account.
- Create a new project. Click "Create a project", then "Connect to Git". Select your repository from the list.
-
Configure the build settings. If your site is plain HTML, leave the build command blank and set the output directory to
/or wherever yourindex.htmllives. For Hugo, set the build command tohugoand output topublic. For Jekyll, usejekyll buildand output to_site. -
Deploy. Click "Save and Deploy". Cloudflare will clone your repository, run the build, and publish to their global edge network. Your site gets a
*.pages.devsubdomain immediately. -
Add a custom domain. In your project dashboard, go to "Custom domains" and enter your domain. If your domain is already managed by Cloudflare DNS, the setup is one click. If not, you will need to add a CNAME record at your registrar pointing to your
*.pages.devaddress.
Every subsequent git push to your main branch will trigger an automatic redeploy. Cloudflare also creates preview deployments for pull requests, which is useful for reviewing changes before they go live.
Adding a Contact Form to Your Static Site
Here is where most guides stop, and where most people get stuck. A contact form on a static website cannot submit data to itself - there is no server listening. You have three realistic options:
- A form backend service (recommended): You point your form's
actionattribute at a third-party endpoint that receives the submission, validates it, and emails it to you. - A serverless function: You write a small function (Cloudflare Workers, AWS Lambda) that processes the form. This works but requires code and ongoing maintenance.
- JavaScript fetch(): You use the browser's fetch API to post form data to a backend endpoint. See our guide on how to send HTML form data with JavaScript fetch() for the technical details.
The fastest path to a working form is a dedicated form service. Here is a concrete example using Sendform:
Concrete Example: A Working Contact Form in 5 Minutes
Suppose you have a portfolio site deployed on GitHub Pages. You want visitors to be able to send you a message, and you want those messages delivered to your inbox. Here is the complete HTML:
<form action="https://sendform.io/f/YOUR_FORM_ID" method="POST">
<label for="name">Your Name</label>
<input type="text" id="name" name="name" required>
<label for="email">Your Email</label>
<input type="email" id="email" name="email" required>
<label for="message">Message</label>
<textarea id="message" name="message" rows="5" required></textarea>
<button type="submit">Send Message</button>
</form>That is the entire integration. You replace YOUR_FORM_ID with the ID from your Sendform dashboard, and every submission is emailed to the address you registered with. No backend code, no server, no monthly infrastructure bill. For more advanced UX patterns, including redirect pages after submission and confirmation emails, read our guide on static website forms best practices.
If you are using a website builder alongside your static site, we also cover the integration process in detail in our article on how to integrate Sendform with your website builder.
Spam protection note: Any publicly accessible form will attract bot submissions. Sendform includes built-in honeypot fields and rate limiting. For a deeper look at keeping your inbox clean, see our article on spam protection best practices for forms.
Common Mistakes to Avoid
After helping thousands of users set up free static web hosting, these are the errors that cause the most frustration:
1. Forgetting the 404 page
Both GitHub Pages and Cloudflare Pages will serve a generic error page if a route is not found. Create a custom 404.html file in your root directory. This keeps users on your site and protects your brand experience.
2. Committing secrets to a public repository
API keys, form endpoint secrets, and email addresses should never live in a public GitHub repository. Use environment variables in Cloudflare Pages, or reference a private configuration file that is listed in .gitignore.
3. Building a form without a backend plan
This is the most common mistake. Developers build a beautiful contact form, push to GitHub Pages, and discover on launch day that the form silently fails. Decide on your form backend before you write a single <input> tag. Tools like Sendform let you set up a contact form that sends straight to email without any code, which removes the backend problem entirely.
4. Ignoring build cache issues
If your site is not updating after a push, the CDN cache may be serving stale files. Cloudflare Pages automatically purges its cache on deployment. GitHub Pages is slower to propagate changes; wait up to 10 minutes, or append a query string to your asset URLs during testing.
5. Using relative paths incorrectly
If your GitHub Pages site lives at username.github.io/project-name/ (a subdirectory), all asset paths must account for that prefix. A link to /styles.css will break. Use relative paths (./styles.css) or configure your static site generator's baseURL setting to match the subdirectory.
6. Skipping form workflow automation
Once your form is collecting submissions, you can do much more than just receive emails. Sendform supports webhooks and integrations that let you route submissions to Slack, a CRM, or a spreadsheet automatically. Our guide on automating form workflows with webhooks and APIs shows you exactly how to set this up without writing backend code.
Conclusion
Free static website hosting has never been more capable. GitHub Pages suits teams already embedded in the GitHub ecosystem, while Cloudflare Pages offers better global performance and a more generous free tier. The real challenge is not the hosting itself - it is the dynamic features, particularly contact forms, that trip people up. By pairing either platform with a dedicated form service, you get a fully functional, professional website at zero infrastructure cost. Start with one of the platform guides above, get your site live, and then wire up your contact form using Sendform to handle submissions reliably from day one.

Add a Contact Form to Your Static Site in Minutes
Use Sendform to collect form submissions from any static site hosted on GitHub Pages or Cloudflare Pages. No backend code, no server setup, no hassle. Just point your form's action attribute at your endpoint and you're done.
Get Started Free at Sendform.net →
Frequently Asked Questions
Yes, for most business use cases. Both GitHub Pages and Cloudflare Pages offer 99.9%+ uptime backed by enterprise infrastructure. The main limitation is the lack of server-side processing, not reliability. For high-traffic or e-commerce sites, you may eventually outgrow the free tier, but for landing pages and portfolios, free hosting is production-grade.
Yes. Both GitHub Pages and Cloudflare Pages support custom domains on their free plans, including automatic HTTPS via SSL certificates. You need to own the domain and update your DNS records to point to the hosting platform. The process takes under 15 minutes and SSL is provisioned automatically within a few hours.
Static sites cannot process form submissions natively because there is no server running. The standard solution is to point your form's action attribute at a third-party form backend service. That service receives the POST request, validates the data, and forwards it to your email. Sendform is one such service that requires no code to configure.
GitHub Pages is simpler and integrates directly with GitHub repositories, making it ideal for developers already using GitHub. Cloudflare Pages offers a faster global CDN with 300+ edge locations, unlimited bandwidth on the free tier, and built-in CI/CD with preview deployments. For performance-sensitive sites, Cloudflare Pages is the stronger choice.
Basic HTML knowledge is helpful, but you do not need to be a developer. Tools like Hugo, Jekyll, or even plain HTML files work perfectly on both platforms. For contact forms, services like Sendform require only a copy-paste HTML snippet, so no backend programming knowledge is needed at any stage of the setup process.