Domain Setup Guide

How to point your Web3 domain to a website, so it loads in OBIAN.

Overview

OBIAN resolves non-ICANN domains (like .eth, .blockchain, .agt, .b2b) to content. You have two hosting options:

Option A: IPFS (decentralized)

  1. Create your site, an HTML file or directory
  2. Upload it to IPFS, get a content identifier (CID)
  3. Publish to IPNS, get a stable name that auto-updates on future deploys
  4. Set a record on your domain, point it to the IPFS content

Option B: HTTP hosting (GitHub Pages, Vercel, any web server)

  1. Deploy your site to any HTTP host
  2. Set a redirect or A record on your domain, point it to the hosting URL

IPFS is fully decentralized but requires an IPFS node for deploys. HTTP hosting is simpler and supports multi-page sites with full CSS/JS/navigation natively. The browser handles both: IPFS content loads in an iframe, and HTTP sites load in a per-tab webview with scroll/form state preserved across tab switches. In both cases, the URL bar shows your Web3 domain name.

HTTP Hosting (GitHub Pages)

The simplest way to get a multi-page site behind a Web3 domain. No IPFS node needed.

Step 1: Create Your Site

Create your HTML/CSS/JS files as normal. Unlike IPFS, you can use multiple pages with navigation, links between pages work natively in the browser's webview.

Step 2: Deploy to GitHub Pages

  1. Create a GitHub repository (or use an existing one)
  2. Push your site files to a gh-pages branch:
    git checkout --orphan gh-pages
    git rm -rf .
    # Copy your site files into the repo root
    git add .
    git commit -m "deploy site"
    git push origin gh-pages
  3. GitHub Pages serves your site at https://<username>.github.io/<repo>/

If Pages isn't enabled automatically, go to Settings → Pages and set the source to the gh-pages branch.

Step 3: Point Your Domain

Choose the method for your domain platform:

Freename: Use the Forward Domain option:

  1. Go to app.freename.ioPortfolio → select your domain
  2. Under domain settings, find Forward Domain
  3. Enter your GitHub Pages URL (e.g., https://username.github.io/repo/)
  4. Save

Unstoppable Domains: Use Website Redirect:

  1. Go to unstoppabledomains.comMy Domains → select your domain
  2. Click Manage → Website
  3. Under Website Redirect, enter your GitHub Pages URL
  4. Save and confirm the transaction

Handshake: Use an A record or TXT redirect:

  • A record: Point to your web server's IP (not applicable for GitHub Pages directly)
  • TXT redirect: Set a TXT record with dnslink=/ipns/... pointing to IPNS-published content (see IPFS section below)

Note on redirects: If your GitHub Pages uses a custom domain (e.g., example.com), the browser automatically detects the redirect and still shows your Web3 domain in the URL bar. For example, navigating within schmitz.agt shows schmitz.agt/about.html even though the content is served from schmitz.ai/web3-browser/about.html.

Other HTTP Hosts

Any HTTP host works, Vercel, Netlify, Cloudflare Pages, a VPS, etc. The setup is the same: deploy your site, then set a redirect record on your Web3 domain pointing to the hosting URL.

IPFS Hosting (Decentralized)

For fully decentralized hosting where content is stored on the IPFS network.

Step 1: Create Your Page

Create an HTML file. For a quick test, create my-site/index.html:

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>My Web3 Site</title>
  <style>
    body {
      font-family: system-ui, sans-serif;
      background: #0a0a0a;
      color: #e0e0e0;
      display: flex;
      align-items: center;
      justify-content: center;
      min-height: 100vh;
      margin: 0;
    }
    .container { text-align: center; max-width: 500px; }
    h1 { font-size: 2rem; margin-bottom: 0.5rem; }
    p { color: #888; }
  </style>
</head>
<body>
  <div class="container">
    <h1>Hello from IPFS</h1>
    <p>This page is served from the decentralized web.</p>
  </div>
</body>
</html>

Important: All CSS and JavaScript must be inline (in the HTML file) or included as relative files in the same directory. External CDN links won't load reliably from IPFS.

Step 2: Deploy to IPFS and IPNS

Prerequisites

  • IPFS Desktop or ipfs daemon running locally
  • Node.js installed

Deploy a single file

node scripts/deploy.js my-site/index.html mydomain.tld

Deploy a directory (for multi-page sites)

node scripts/deploy.js my-site/ mydomain.tld

What the deploy script does

  1. Uploads your file(s) to IPFS via your local IPFS node
  2. Publishes the CID to IPNS so the name stays constant across updates
  3. Prints the CID, IPNS key, and setup instructions for your domain type

Example output

  [1/3] Uploading to IPFS...
        index.html  (542 bytes)

        CID: QmW3fKQG7hD1TB8rbZcXKfJ53HkdfMMrnzg4pbvdQB8drg

  [2/3] Publishing to IPNS (key: self)...
        Key ID: k51qzi5uqu5dkbm9dousj5w5i9qfleq6t9ffyhc19us5oo...
        Published: k51qzi5uqu5... -> /ipfs/QmW3fKQG7hD1TB8r...

  [3/3] Summary

        IPFS:    ipfs://QmW3fKQG7hD1TB8rbZcXKfJ53HkdfMMrnzg4pbvdQB8drg
        IPNS:    ipns://k51qzi5uqu5dkbm9dousj5w5i9qfleq6t9ffyhc19us5oo...
        Gateway: https://ipfs.io/ipns/k51qzi5uqu5...

Save the CID (starts with Qm or bafy) and the IPNS Key ID (starts with k51). You'll need one of these for the next step.

CID vs IPNS: Which to use?

CID (static)IPNS (auto-updating)
FormatQmW3fKQG7hD1...k51qzi5uqu5dkbm9...
UpdatesMust change the domain record every time you deployDomain record stays the same forever
SpeedInstant (content is already pinned)Slight delay (IPNS lookup adds ~1-2 seconds)
RecommendedOne-off pages that won't changeAny site you plan to update

We recommend IPNS for most use cases. Set it once, then every future node scripts/deploy.js automatically updates what the domain points to.

Set Your Domain Record

Choose the section below that matches where your domain is registered.

ENS Domains (.eth)

ENS domains store a content hash on the Ethereum blockchain.

Setup (one-time, requires a transaction):

  1. Go to app.ens.domains and connect your wallet
  2. Select your domain
  3. Click Edit RecordsContent Hash
  4. Set to your IPNS key:
    ipns://k51qzi5uqu5dkbm9dousj5w5i9qfleq6t9ffyhc19us5oo...
    Or for a static CID:
    ipfs://QmW3fKQG7hD1TB8rbZcXKfJ53HkdfMMrnzg4pbvdQB8drg
  5. Save and confirm the transaction in your wallet

Updating your site: If you used IPNS, just run the deploy script again. No transaction needed, the IPNS name automatically points to your new content.

Cost: One-time gas fee on Ethereum mainnet to set the content hash. Free updates after that if using IPNS.

Unstoppable Domains (.blockchain, .x, .unstoppable, .web3, .888, etc.)

Unstoppable Domains store records on the Polygon and Ethereum blockchains. The browser reads them directly from UD's ProxyReader smart contracts, no API key needed.

Supported TLDs: .888, .blockchain, .x, .unstoppable, .web3, .moon, .go, .super, .dream, .og, .hi, .tea, and 120+ more.

Setup (one-time, requires a transaction):

  1. Go to unstoppabledomains.com and log in
  2. Select your domain from My Domains
  3. Click ManageWebsite
  4. Choose how to point your domain to content:

Option A: IPFS hash (recommended for static sites):

  1. Under IPFS Hash, paste your CID:
    QmW3fKQG7hD1TB8rbZcXKfJ53HkdfMMrnzg4pbvdQB8drg
  2. Click Save Changes and confirm the transaction

This sets the dweb.ipfs.hash record on-chain. You'll need to update it each time you deploy.

Option B: Redirect URL (simplest):

  1. Under Website Redirect, enter your IPNS gateway URL:
    https://ipfs.io/ipns/k51qzi5uqu5dkbm9dousj5w5i9qfleq6t9ffyhc19us5oo...
  2. Click Save Changes and confirm the transaction

This sets the ipfs.redirect_domain.value record. The browser will fetch content from the redirect URL. Because it points to your IPNS name, future deploys auto-update without a new transaction.

Option C: IPFS hash via programmatic records (advanced):

If you manage records via UD's developer tools or a dApp, set these keys:

KeyValueNotes
dweb.ipfs.hashQmW3fKQG7hD1... or bafybeig...IPFS CID (highest priority)
ipfs.html.valueQmW3fKQG7hD1...Legacy IPFS key (also works)
dweb.arweave.hashArweave TX IDFor Arweave-hosted content
ipfs.redirect_domain.valuehttps://example.comHTTP redirect
browser.redirect_urlhttps://example.comAlternative redirect key

The browser checks these keys in the order listed and uses the first non-empty value.

Updating your site:

  • If you set an IPFS hash: update the record and sign a new transaction each time.
  • If you set a redirect to an IPNS gateway URL: just run the deploy script again. No transaction needed.

Which chain? Most UD domains are minted on Polygon. The browser checks Polygon first, then falls back to Ethereum. You don't need to configure which chain, the browser finds your domain automatically.

Cost: Small gas fee on Polygon (typically < $0.01) per record update. Ethereum transactions cost more if your domain is on L1.

Freename Domains (.agt, .token, .metaverse, etc.)

Freename domains store records as on-chain data on the FNS smart contract. The browser resolves them via the Freename API and on-chain fallback across Polygon, Base, Aurora, Cronos, and BSC.

Prerequisites:

  • Domain must be in your personal wallet (not Freename Custody)
  • MetaMask connected to the correct network (usually Polygon)

Setup:

  1. Go to app.freename.ioPortfolio → select your domain
  2. Click the Records tab
  3. Under Web3 Records, click Add a Record
  4. Set:
    • Type: IPFS
    • Value: Your CID (e.g., QmW3fKQG7hD1TB8rbZcXKfJ53HkdfMMrnzg4pbvdQB8drg)
  5. Click Save Record
  6. Click Sign Transaction and confirm in MetaMask

Updating your site: You'll need to update the IPFS record and sign a new transaction each time. Freename's Web3 records use static CIDs, there's no native IPNS support in their Web3 record UI.

Alternative: IPNS via DNS TXT record:

If your Freename domain has DNS management (noto.network nameservers), you can set a TXT record instead:

  1. In the DNS Records section, click Add a Record
  2. Set:
    • Type: TXT
    • Host: @
    • Value: dnslink=/ipns/k51qzi5uqu5dkbm9dousj5w5i9qfleq6t9ffyhc19us5oo...
  3. Save

This gives you auto-updating content without signing new transactions on each deploy.

Custody wallet domains: If your domain is in Freename's Custody Wallet, you may not be able to sign record updates. Transfer the domain to your personal wallet first: Portfolio → select domain → Transfer → paste your wallet address → confirm via email OTP.

Cost: Small gas fee on Polygon (typically < $0.01) per record update.

Handshake Domains (.b2b, .performer, any non-ICANN TLD)

Handshake domains use traditional DNS records, served through the Handshake blockchain's root zone. The browser resolves them via DNS-over-HTTPS.

DNS delegation chain:

Handshake blockchain → TLD nameservers (e.g., Namebase)
  → Domain nameservers (e.g., Namecheap)
    → Your DNS records (A, TXT, CNAME)

Namecheap Setup

If your Handshake domain is managed through Namecheap (delegated via Namebase):

  1. Log into NamecheapDomain List → select your domain
  2. Go to Advanced DNS
  3. Click Add New Record
  4. Set:
    • Type: TXT Record
    • Host: @
    • Value: dnslink=/ipns/k51qzi5uqu5dkbm9dousj5w5i9qfleq6t9ffyhc19us5oo...
    • TTL: Automatic (or 1 minute for testing)
  5. Save

Important: Use @ as the Host, not the subdomain name. For example, for ai.b2b, the Host is @ (not ai). The subdomain is part of the zone that Namebase delegates to Namecheap, setting Host to ai would create a record for ai.ai.b2b.

Updating your site: Run the deploy script again. The IPNS name stays the same, so no DNS changes needed.

Using a static CID instead of IPNS:

Set the TXT value to:

dnslink=/ipfs/QmW3fKQG7hD1TB8rbZcXKfJ53HkdfMMrnzg4pbvdQB8drg

You'll need to update the DNS record every time you deploy.

Cost: Free (DNS records don't cost anything).

Other DNS Providers

The TXT record setup is the same regardless of DNS provider. The key details:

  • Record type: TXT
  • Host/Name: @ (or leave blank, depending on the provider)
  • Value: dnslink=/ipns/{your-key-id} or dnslink=/ipfs/{your-cid}

Verifying Your Setup

Check DNS records (Handshake)

From a terminal, query your domain's TXT record through Handshake DNS:

nslookup -type=TXT yourdomain.tld 103.196.38.38

103.196.38.38 is a Handshake DNS resolver (a.hdns.io). You should see your dnslink value in the response.

Check Freename API

curl https://apis.freename.io/api/v1/resolver/FNS/yourdomain.tld

Look for your IPFS record in the records array.

Check IPFS content

Visit the IPFS gateway URL from the deploy output:

https://ipfs.io/ipns/{your-key-id}

If the page loads in a regular browser, it will load in OBIAN.

Check Unstoppable Domains records

UD records are stored on-chain. You can verify them at:

https://unstoppabledomains.com/d/{yourdomain.tld}

Or check the domain's page in your UD account under Manage → Website to confirm that IPFS hash or redirect URL fields are populated and the transaction was confirmed.

Test in OBIAN

  1. Run npm run dev from the project root
  2. Type your domain in the URL bar (e.g., ai.b2b, receipt.agt, yourname.eth, example.blockchain)
  3. The page should load with CSS and JavaScript working

Troubleshooting

"Resolution Failed" error

  • ENS: Check that the content hash is set at app.ens.domains
  • Unstoppable Domains: Check that your domain has records set at unstoppabledomains.com → My Domains → Manage → Website. Records must be saved on-chain (transaction confirmed).
  • Freename: Check the API: curl https://apis.freename.io/api/v1/resolver/FNS/yourdomain.tld
  • Handshake: Check DNS: nslookup -type=TXT yourdomain.tld 103.196.38.38

Page loads but CSS/JS is broken

  • External resources (CDNs, Google Fonts, etc.) may not load when content is served through IPFS
  • Keep all CSS and JavaScript inline or as local files in the same directory
  • Deploy the full directory: node scripts/deploy.js my-site/ (not just the HTML file)

Unstoppable Domains domain not resolving

  • Make sure the transaction that set your records was confirmed on-chain (check your wallet history on Polygonscan or Etherscan)
  • If your domain was recently minted, records may take a few minutes to be queryable via RPC
  • The browser checks Polygon first, then Ethereum; if your domain is on Ethereum L1, resolution may be slightly slower
  • Verify the domain has a dweb.ipfs.hash, ipfs.redirect_domain.value, or another supported record set (crypto wallet addresses alone won't produce a website)

Freename domain not found on API

  • The domain may be in Freename's Custody Wallet, transfer to your personal wallet
  • The IPFS record may not be signed on-chain yet, check for a "Sign Transaction" button
  • The .agt TLD has known issues with the older rslvr.freename.io API, the browser uses apis.freename.io which indexes all chains

Namecheap TXT record not working

  • Use @ as the Host, not the subdomain name
  • Wait 1-2 minutes after saving for propagation
  • Verify directly: nslookup -type=TXT yourdomain.tld dns1.registrar-servers.com

IPNS is slow or not resolving

  • IPNS lookups add 1-2 seconds on first load; subsequent loads are cached
  • Make sure your IPFS daemon is running and the IPNS key is published
  • Check the gateway: https://ipfs.io/ipns/{key-id}. If this loads, the browser will too

Quick Reference

IPFS Records

PlatformRecord TypeValue Format
ENSContent Hashipns://{key-id} or ipfs://{cid}
Unstoppable Domains (IPFS)IPFS Hash{cid} (just the hash, no prefix)
Unstoppable Domains (redirect)Website Redirecthttps://ipfs.io/ipns/{key-id}
Freename (Web3)IPFS{cid} (just the hash, no prefix)
Freename (DNS)TXTdnslink=/ipns/{key-id}
Handshake (Namecheap)TXT, Host: @dnslink=/ipns/{key-id}
Handshake (other DNS)TXTdnslink=/ipns/{key-id}

HTTP Redirect Records

PlatformMethodValue Format
Unstoppable DomainsWebsite Redirecthttps://username.github.io/repo/
FreenameForward Domainhttps://username.github.io/repo/
HandshakeA recordServer IP address