Key takeaways
- On the Internet Computer (ICP), a website lives in an asset canister: a WebAssembly program that stores your files and answers HTTP requests itself. There is no separate web server or CDN contract.
- Visitors use an ordinary browser. An HTTP gateway translates each request into a canister call and verifies the response's certificate before passing it on.
- Static sites and single-page apps (React, Vite, Astro, Vue, static Next.js exports) work today. Server-rendered apps that need Node.js at request time do not, unless the backend is rewritten as a canister.
- Page views are query calls, and query calls are free. The site owner pays for storage and updates in cycles: 1 trillion cycles is pegged to 1 XDR, about $1.37.
- You can deploy by hand with icp-cli (identity, cycles, icp.yaml, icp deploy), or let a managed host like Webstead create the canister, fund it and connect your domain.
Hosting a website on the Internet Computer sounds more exotic than it is. Your visitors type a URL, the page loads over HTTPS, and nothing about the experience says "blockchain." What changes is everything behind the URL: there is no server you rent, no CDN contract, and no single company that can switch your site off.
This guide explains what is actually happening, what you can and can't host, and the two practical ways to get a site live.
What "hosting on ICP" means
The Internet Computer (ICP) is a public blockchain network that runs general-purpose programs called canisters. A canister bundles WebAssembly code with its own memory, and it is replicated across a subnet: a group of independent machines (13 or more nodes on a standard application subnet) that run the same code and agree on its state.
A website on ICP lives in an asset canister, a canister whose job is to store files (HTML, CSS, JavaScript, images) and answer HTTP requests for them. It is your web server, file storage and certificate authority rolled into one program. Because it runs on a subnet of many nodes rather than one machine, a single hardware failure doesn't take the site down.
- CDN / edge cache
- Load balancer
- Web server (VM or container)
- Disk / object storage
- TLS certificate you renew
- HTTP gateway (anyone can run one)
- API boundary nodes
- Subnet: 13+ replicated nodes
- Asset canister: code + your files
- Certified responses, auto TLS
How a page request reaches your canister
Browsers don't speak the Internet Computer's protocol, so a translation layer sits in between. Here is the full path of one request to yoursite.com:
- BrowserRequests yoursite.com over ordinary HTTPS. No wallet or plugin.
- DNSYour domain points at an ICP HTTP gateway, which maps it to a canister ID.
- HTTP gatewayTurns the HTTP request into a canister call, then checks the response's certificate before returning it.
- API boundary nodeRoutes the call to the subnet that hosts your canister.
- Subnet + canisterA replica on a 13+ node subnet runs the asset canister and answers with your file.
- Browser. A normal HTTPS request. No extension, no wallet.
- DNS. Your domain points at an ICP HTTP gateway. A TXT record tells the gateway which canister ID serves that hostname.
- HTTP gateway. Converts the HTTP request into a canister call. HTTP gateways are not part of the protocol itself, and anyone can run one.
- API boundary node. The network's public entry point. It routes the call to the subnet hosting your canister.
- Subnet and canister. A replica runs your asset canister's
http_requesthandler and returns the file.
The interesting part is step 3 on the way back. A page view is a query call, answered by a single replica without going through consensus, which keeps it fast. To stop a faulty or malicious node from serving altered content, the asset canister certifies its files in advance: the subnet signs a Merkle tree of the content, and the gateway checks the response against that signature before it hands anything to the browser. If the check fails, the visitor gets an error instead of a tampered page.
What you can host (and what you can't)
ICP hosts anything that ends up as files in a folder, and it can also run real backends, just not the kind you're used to.
| You want to host | Works on ICP? | Notes |
|---|---|---|
| Static HTML/CSS/JS site | Yes | The simplest case: upload the folder. |
| Single-page app (React, Vue, Svelte, Vite) | Yes | Needs a rewrite of unknown paths to index.html so deep links work. |
| Static site generator (Astro, Hugo, Eleventy, Jekyll) | Yes | Deploy the build output directory. |
Next.js with output: "export" | Yes | Static export only. Image optimisation and API routes are unavailable. |
| Next.js / Nuxt / SvelteKit with server rendering | No | Needs Node.js at request time, which a canister doesn't provide. |
| WordPress, PHP, Rails, Django | No | Traditional servers and SQL databases don't run in a canister. |
| App with its own backend logic and data | Yes, rewritten | Write the backend as a canister in Motoko or Rust; the frontend calls it directly. |
That last row is where ICP differs from static hosts like GitHub Pages. A backend canister can hold state (up to hundreds of GiB of stable memory), serve an API and talk to other canisters, so a full app can live on the network with no external server at all. Webstead deploys Motoko backends alongside their frontend for exactly this reason, including apps exported from the Caffeine AI builder.
Option 1: deploy it yourself with icp-cli
DFINITY's command-line tool, icp-cli, is the current way to deploy canisters by hand. The broad steps:
- Install icp-cli (it is distributed through npm as
@icp-sdk/icp-cli) and create an identity. The identity's principal is who controls the canister. - Get cycles. Buy ICP on an exchange, send it to your identity's ledger account (
icp identity account-idprints it), then convert it withicp cycles mint --icp <amount> -n ic. Cycles are held against your principal by the cycles ledger. - Describe the site in
icp.yaml. The@dfinity/static-siterecipe takes your build commands and output folder:
canisters:
- name: frontend
recipe:
type: "@dfinity/static-site@v0.4.0"
configuration:
build:
- npm ci
- npm run build
dir: dist
- Deploy to mainnet with
icp deploy -e ic frontend. The first run creates the canister (paying the creation fee from your cycles), installs the asset canister code and uploads your files. - Add SPA routing if you need it. For a single-page app, put a
_redirectsfile containing/* /index.html 200at the root of the output folder. - Keep it funded. Watch the canister's balance and top it up with
icp canister top-up <canister-id> --amount <cycles> -n icbefore it runs low.
The site is then live at https://<canister-id>.icp0.io (newer tooling prints the equivalent icp.net address). A custom domain is a separate step, covered below.
This route gives you full control and costs only the cycles you burn. The price is that you are now the operator: you hold the keys, buy the ICP, mint the cycles, watch the balance and set up DNS. Lose the identity's key and you lose control of the canister.
Option 2: use a managed ICP host
A managed host does the operator work and leaves you with the developer experience of Netlify or Vercel. With Webstead, for example:
- Connect a GitHub repo and the framework is detected; every push to your branch redeploys. Or upload a folder or zip with no Git at all.
- The build runs in a sandbox, and the result is deployed to a fresh asset canister on ICP mainnet.
- Cycles are funded and monitored for you. The dashboard shows runway in days rather than a 12-digit balance, and warns before anything freezes.
- You get a free
yoursite.webstead.appsubdomain, and a wizard generates the DNS records for your own domain.
The trade-off is custody: during the beta, Webstead controls the canisters and funds their cycles on your behalf. Your site is still an ordinary asset canister on the public network, so moving to self-custody later doesn't mean rebuilding anything.
| DIY with icp-cli | Managed (Webstead) | |
|---|---|---|
| Setup | Identity, ICP purchase, cycle minting, icp.yaml | Connect GitHub or upload a folder |
| Cycles | You buy, mint and top up | Funded and monitored for you (free in beta) |
| Redeploys | Run icp deploy yourself or script CI | Automatic on every push |
| Custom domains | Write DNS records and the ic-domains file by hand | Records generated and checked for you |
| Who controls the canister | Your principal | Webstead during beta, self-custody later |
Connecting a custom domain
The ICP gateways issue TLS certificates for custom domains automatically, but they need proof that you own the domain and that the canister agrees. That takes three DNS records and one file:
- A CNAME from your hostname to the ICP gateway.
- A TXT record (
_canister-id.yourdomain) containing the canister ID. - An ACME challenge CNAME so the gateway can obtain a certificate.
- A
/.well-known/ic-domainsfile in the canister listing the hostname, so a domain can't be pointed at a canister that never agreed to it.
Then you register the domain with the gateway, and within a few minutes it serves your site over HTTPS. Subdomains (www.example.com) are the easiest; a bare apex domain needs a DNS provider that supports ALIAS, ANAME or CNAME flattening. If you use Cloudflare, keep the records DNS-only (grey cloud) so the gateway can see them. Our custom domains guide walks through each record.
Is it fast, and is it good for SEO?
Search engines see an ICP site like any other. Crawlers fetch the same HTML over the same HTTPS, so titles, meta descriptions, canonical tags, sitemaps and structured data all work as usual. The usual static-site advice applies: a pre-rendered site (Astro, Hugo, a static Next.js export) is easier to index than a client-only SPA that builds its content in JavaScript.
Speed depends on the gateway nearest your visitor and on caching. Query calls skip consensus, so they return quickly, and the gateways cache responses. Treat your own site as the benchmark: deploy it and measure it rather than relying on anyone's headline numbers, ours included.
When ICP is the right choice
ICP hosting earns its keep when who controls the site matters: a project that shouldn't depend on one cloud account, a community or DAO site, a web3 app's frontend that should be as tamper-resistant as its contracts, or anyone who wants their site to keep running regardless of a single provider's decisions. It is also a natural home for apps whose backend can live in a canister too.
If you need server-side rendering, a SQL database or a PHP CMS, a conventional host is still the simpler answer. For everything that builds to a folder of files, the Internet Computer is a real option today, and the cost is lower than most people expect. Our explainer on canisters, cycles and what ICP hosting costs does the arithmetic.
Frequently asked questions
Can I host a website on the Internet Computer?
Yes. Any static site or single-page app can be served from an asset canister on ICP. Browsers reach it through an HTTP gateway at <canister-id>.icp0.io (or icp.net) or at your own custom domain, with HTTPS handled for you.
Is hosting a website on ICP free?
Visitors never pay, and page views (query calls) cost nothing. The canister itself needs cycles for storage and updates. For a small static site that is a few dollars a year: about 0.5T cycles to create the canister, roughly half a trillion more to install it, and on the order of 5 billion cycles a day to keep it running. Webstead covers these cycles during its free beta.
Do my visitors need a crypto wallet?
No. The site loads in any browser over normal HTTPS. Wallets only matter if your app asks visitors to sign in with Internet Identity or to make on-chain payments.
Can I run Next.js, WordPress or a Node.js server on ICP?
Not as a traditional server. A Next.js app with output: 'export' deploys fine as static files. Server-side rendering, API routes, PHP and long-running Node processes need a server ICP doesn't provide. The ICP-native alternative is a backend canister written in Motoko or Rust.
Can I use my own domain name?
Yes. You add a CNAME pointing at the ICP gateway, a TXT record naming your canister, and an ACME challenge CNAME so a TLS certificate can be issued, and the canister must list the domain in /.well-known/ic-domains. Webstead generates these records and the ownership file for you.
What happens to my site if the canister runs out of cycles?
When the balance drops below the freezing threshold (by default enough for 30 days of idle cost), the canister freezes and stops answering requests, so the site goes offline. Topping it up brings it back. If the balance reaches zero the code and files are uninstalled, so keep a buffer or use a host that monitors it.