In recent years, startups (and a few tech giants) have rolled out new hosting products that follow a “commit-to-publish” model: developers merge new code (or content) into their repository’s main branch—then relax as robots handle the drudgework of pulling commits, rebuilding packages, running tests, and ultimately deploying a new website or app to production—replacing whatever was previously there.

Platforms like Netlify, Vercel, Remix, and have made it easier than ever for maintainers of static sites to spend less time publishing and more time developing their product.

One such platform, Fleek, aims to give developers the same effortless publishing flow, but with a twist: the static (or client-side) site builds generated by the platform can be instantly published to IPFS: an open, trustless, peer-to-peer file-hosting network accessible by anyone, from anywhere, through the Internet. As a consequence, websites hosted with IPFS are made immune to illicit tampering, centralized points-of-failure as well as corporate and government censorship.

We’re going to look at the (delightfully few) steps involved in publishing a Hugo project (such as this very website) to IPFS using Fleek’s in-browser tools—and, in doing so, stake our own, small claim on the “new Internet” that is web3.


A decentralized web awaits…

Logging In

Fleek supports registration via GitHub, so that’s what we’ll be using. From the homepage, click Sign InSign In With GitHub. By authenticating through GitHub, you grant Fleek read-access to your GitHub repositories. If later you want to revoke access, or limit Fleek to only certain repos, you can do that through your GitHub settings. If your GitHub account has 2FA enabled, you’ll be prompted to enter a code. If not, I strongly recommend you set it up today.


Signing in with GitHub


Authorizing Fleek to read your repository

Linking your Hugo Project

Upon login, you’ll be taken to the Hosting screen. This is where you can create new “sites” (project deployments) and view your existing sites. To continue, click the Add new site button.


Creating a new site

On the Create a new site screen, you’ll need to authorize Fleek to work with GitHub again. This is because Fleek needs permission to connect its background services to your GitHub project—allowing those services to run in response to new push events.


Connecting the Fleek app to GitHub

Click Connect with GitHub. You should see your GitHub profile name and photo, along with a list of GitHub repositories. Find the name of the Hugo project you want to deploy, and click it. If you don’t already have a Hugo project, or your project isn’t hosted on GitHub, feel free to fork mine.

$ git clone


Choosing your project's repository

The next step is to choose a decentralized hosting network for your site to live on. Fleek offers two deploy locations today: IPFS, and Internet Computer. For this example, we’ll choose IPFS.


Choosing IPFS as our (decentralized) deploy location

Fleek will pre-select your repository’s default branch (e.g., main) as the branch from which to build.


Choosing the build branch

Building for Hugo

The final step is to tell Fleek’s robots how to build our website—Fleek will handle the deployment thereafter. Depending on your project’s setup, Fleek may automatically detect Hugo as your project’s framework. If not, just set the Framework option to “Hugo”.


Selecting Hugo as your framework

Fleek will map your choice of Framework to three pieces of configuration:

  1. A particular Docker image (which Fleek’s robots use to setup and build your project)
  2. A default build command (specific to your project’s framework)
  3. A publish directory (which Fleek uses to determine which generated files constitute the finished site build; these are the files that will be published to IPFS following each build)

Perhaps your Hugo project has certain build dependencies that you install with a package manager like npm or yarn. In that case, you can replace the default build command (hugo) with something custom (e.g., npm install && npm run build).


Customizing the build command for Hugo

For a Hugo project, Fleek’s publish directory should be synonymous with Hugo’s top-level publishDir setting. If you’ve changed this Hugo setting to something other than its default ("public"), make sure to supply the same custom path as the publish directory option.

Finally, the base directory supports projects for which hugo should be run in some directory other than the project’s root directory. This probably doesn’t apply to you.

If your Hugo project uses the .Permalink and .RelPermalink page variables, things should work just fine on IPFS. However, if all or some of your Hugo links are canonical (i.e., prefixed by a baseURL like, you might end up sending visitors away from your IPFS site instance to another domain (that is, unless you’ve configured your web domain’s DNS records to point to the IPFS instance).

Make sure your Hugo project has canonifyURLs set to false, and that your site links aren’t generated with a baseURL.

Overriding Hugo Options

It’s worth noting that, with Fleek, you can take advantage of Hugo’s built-in support for Hugo environment variables. By taking any supported configuration setting and converting it to CONSTANT_CASE (with a HUGO_ prefix), you’re left with an environment variable that Hugo detects whenever it runs.

If, for example, you wanted to customize your website’s title setting for Fleek builds, you can add HUGO_TITLE (with a custom value) under Environment Variables. This effectively overrides the existing title setting in your project’s configuration file(s). This is handy even for non-Fleek sites, when you want to customize your Hugo config on a per-target-basis.


Customizing Hugo via environment variables


With the proper build command (and environment variables) in place, start the deploy process by clicking Deploy site. This will navigate you to the Deploys tab, where you can monitor the deployment log and check for build errors.


Deployment in progress

At the bottom of the log, after the Hugo output, you should find your website’s current root IPFS hash, along with a newly-generated URL for Fleek’s CDN (e.g., This is Fleek letting you know that the deployment was a success and that your new website is now available to view on IPFS.

10:45:58 PM 11/21/2021:
10:45:58 PM 11/21/2021: Pages | 41
10:45:58 PM 11/21/2021: Paginator pages | 0
10:45:58 PM 11/21/2021: Non-page files | 1062
10:45:58 PM 11/21/2021: Static files | 926
10:45:58 PM 11/21/2021: Processed images | 0
10:45:58 PM 11/21/2021: Aliases | 0
10:45:58 PM 11/21/2021: Sitemaps | 1
10:45:58 PM 11/21/2021: Cleaned | 0
10:45:58 PM 11/21/2021: Total in 366 ms
10:46:04 PM 11/21/2021: Deployed to IPFS and got the hash:
10:46:04 PM 11/21/2021: QmeWPVtxaQxDwNKifyvepF3By7shrtk1w2RDiq4rmBuPd1
10:46:04 PM 11/21/2021: Checking content availability on IPFS...
10:46:05 PM 11/21/2021: Updating DNS records...
10:46:06 PM 11/21/2021: DNS was updated. You can visit the new site at:
10:46:06 PM 11/21/2021:


Deploy History

If everything went well, you should see a Deploy Status of “Published deploy”. Above the Deploys tab, on the right, you should even see a thumbnail snapshot of the deployed website.

Click the Back to all deploys link to view the deploy list.

Fleek keeps a history of each deploy that it runs, including the result (i.e., success or failure). Deploys are tagged with the branch and commit hash associated with that build—simplifying tracking.


Viewing the deploy history

Finishing Touches

On your site screen, Fleek now displays the generated CDN URL for our website (e.g.,, along with a “Last published” time and an IPFS link.


Viewing our site links


Accessing the deployed site through Fleek's centralized CDN

Updating the Site Name

For our project, we can customize the site name to match our repository name. Navigate from the Deploys tab to the Settings tab. Under GeneralSite DetailsSite Information, click the Change Site Name button. Enter a suitable subdomain (e.g., zalla-io-website). Fleek will show a preview of your customized CDN URL. This is also useful if you want to experiment with different deploy options for the same repository and thus need to distinguish each “site” experiment by name.


Updating the site name to match our project


Viewing the updated site name

Viewing on IPFS

On your site screen, click the Verify on IPFS link. This opens a link to your website on IPFS, accessed through Fleek’s public IPFS gateway. For example,

Verify that your Hugo site looks and acts as you’d expect:


Accessing the deployed site through Fleek's public gateway

This is nice, but if we really want to verify things on IPFS ourselves, we can access our site using the IPFS protocol directly:

  1. For Brave browser, this URL should work out-of-the-box.
  2. For Chrome, you can install the IPFS Companion Chrome extension.
  3. For Firefox, you can install the IPFS Companion Firefox extension.
  4. For Safari, you can install IPFS Desktop before requesting an ipfs:// URL.

Wrapping Up

By building projects on top of popular frameworks (like Hugo), developers can gain the benefit of sharing common ground with their build tools. The more safe assumptions that your deployment tools can make about your website and how it’s built, the less information we (as developers) need to provide to those tools. This common ground is what makes third-party, zero-configuration (or minimal configuration) publishing solutions possible.

By combining these tools with behind-the-scenes IPFS hosting processes, Fleek brings the same development conveniences to the decentralized web.


It’s worth noting that while Fleek’s CDN and DNS services are centralized (like the rest of the Internet today), neither are necessary if you simply want your website or project hosted on IPFS or Internet Computer. The Fleek team has stated that their “DNS will be centralized until decentralized alternatives are realistic to use as a full replacement"; furthermore, they “have some cool plans to decentralize the CDN aspect of our stack in the future.

I’m no network engineer, but one’s free to speculate: perhaps decentralized publishing solutions could introduce a hybrid model, wherein the client (user) fetches a manifest of hashes directly from an IPFS node, while also fetching the actual file content from a centralized CDN; the client could always hash whatever it received from the CDN to verify that it indeed is the content they asked for.


If you have any thoughts, questions, or corrections to this walkthrough, please drop a comment in the Disqus thread below! If this article helped you publish your own decentralized site on IPFS, please drop the ipfs:// link so everyone can check it out!