AIOZ Static Website Deploy
Deploy a static website to AIOZ decentralized storage. Supports 4 built-in templates or user's own static site.
FLOW OVERVIEW
CODEBLOCK0
STEP 1: LOGIN
Ask user for AIOZ Storage email and password.
CODEBLOCK1
Response: data.access_token (Bearer token), data.account.id (accountId).
Store BEARER_TOKEN and ACCOUNT_ID.
STEP 2: CHOOSE TEMPLATE
Ask user which template or if they have their own static site.
Templates from https://github.com/AIOZStorage/aioz-storage-docs/tree/main/examples:
- 1. landing — OLED dark theme, X/Twitter style landing page. CONFIG in
assets/main.js. - landing-alt — Purple gradient landing page. CONFIG in
assets/main.js. Supports *italic* gradient text in headlines. - portfolio — Clean minimal portfolio for devs/designers. CONFIG in
assets/main.js. Image carousel for projects. - documents — Full documentation site with Markdown content. CONFIG in
assets/js/config.js. Search, TOC, syntax highlighting. - Custom — User provides their own static files.
STEP 3: CLONE TEMPLATE & CUSTOMIZE
Clone the chosen template:
CODEBLOCK2
Then customize the CONFIG object based on template type:
Template: landing
Config: assets/main.js → CONFIG object. Theme: "dark" (OLED black) or "light".
Key fields to customize:
- -
brand.name — brand/product name - INLINECODE14 ,
meta.description — SEO - INLINECODE16 — pill badge (or null to hide),
hero.title, INLINECODE18 - INLINECODE19 —
{ label, href }, INLINECODE21 - INLINECODE22 — toggle: highlights, logos, features, useCases, testimonials, pricingTop, pricingBot, faq
- INLINECODE23 —
{ number, label } stats (numbers animate on scroll) - INLINECODE25 — company name strings
- INLINECODE26 — INLINECODE27
- INLINECODE28 — INLINECODE29
- INLINECODE30 — INLINECODE31
- INLINECODE32 — INLINECODE33
- INLINECODE34 — INLINECODE35
- INLINECODE36 —
"redirect" | "mailto" | INLINECODE39 - INLINECODE40 ,
footer.columns[], INLINECODE42 - Colors in
assets/style.css :root → INLINECODE45
Template: landing-alt
Config: assets/main.js → CONFIG object. Theme: "light" | "dark" | "system".
Key fields to customize:
- -
brand.name, INLINECODE52 - INLINECODE53 — pill badge (or null),
hero.headline (wrap words in *asterisks* for gradient italic text), INLINECODE56 - INLINECODE57 ,
hero.secondaryCta, INLINECODE59 - INLINECODE60 — toggle: stats, problemSolution, features, useCases, logos, testimonials, pricing, faq
- INLINECODE61 —
{ number, label } (numbers animate on scroll) - INLINECODE63 — INLINECODE64
- INLINECODE65 —
{ size, gradient, kicker, title, desc, tag, visual } (bento grid, size: "wide"|"narrow"|"half"|"third"|"full") - INLINECODE67 — INLINECODE68
- INLINECODE69 —
"redirect" | "mailto" | INLINECODE72 - Colors in
assets/style.css → --color-primary: #635bff, --color-gradient-start, INLINECODE76
Template: portfolio
Config: assets/main.js → CONFIG object. Theme: "light" | "dark" | "auto".
Key fields to customize:
- -
personal.firstName, personal.lastName, personal.title, INLINECODE85 - INLINECODE86 — INLINECODE87
- INLINECODE88 ,
about.bio (array of paragraphs), about.focusAreas (array of skill strings) - INLINECODE91 — INLINECODE92
- INLINECODE93 —
{ title, tags[], year, images[], description, techNote, link: { label, url } } (multiple images = carousel) - INLINECODE95 — INLINECODE96
- INLINECODE97 , INLINECODE98
- INLINECODE99 — toggle: showAbout, showExperience, showProjects, showFocusAreas
- INLINECODE100 ,
footer.copyright (null = auto-generate) - INLINECODE102 ,
meta.description, INLINECODE104 - Images in
assets/images/ (1600×900 for projects, 1200×630 for OG)
Template: documents
Config: assets/js/config.js → CONFIG object. Theme: "light" | "dark" | "auto".
Key fields to customize:
- -
site.title, site.description, INLINECODE113 - INLINECODE114 , INLINECODE115
- INLINECODE116 —
{ group, collapsed, items: [{ label, path }] } (path = filename without .md) - INLINECODE118 —
{ label, href }, header.links[] — INLINECODE121 - INLINECODE122 , INLINECODE123
- INLINECODE124 — toggle: search, tableOfContents, feedback, prevNext, copyCodeButton, scrollToTop
- INLINECODE125 — INLINECODE126
- INLINECODE127 — 2 or 3
Content: create .md files in /docs/ with YAML front matter:
CODEBLOCK3
Callouts: > [!NOTE], > [!TIP], > [!WARNING], > [!DANGER]
Code blocks with syntax highlighting (javascript, typescript, python, bash, json, html, css, yaml, sql, go, rust, java, etc.)
Hash routing: index.html#/page-name → loads INLINECODE135
STEP 4: GET BUCKET INFO
Ask user for:
- 1. Bucket name — their bucket on aiozstorage.network
- 12-word seed phrase — BIP39 passphrase from bucket creation
IMPORTANT: AIOZ Storage does NOT store passphrases. If lost, bucket access is lost forever.
See: https://aiozstorage.network/docs/tutorials/manage-buckets
STEP 5: GET ROOT ZKEY
CODEBLOCK4
Extract: ROOT_ZKEY = INLINECODE137
STEP 6: GENERATE GRANT
Prerequisites (one-time setup in {baseDir})
CODEBLOCK5
This installs argon2-browser and ts-node. No build:sjcl needed — the CLI uses Node.js built-in crypto.
Run grant-cli.ts (RECOMMENDED: JSON output for bot)
Two grants are needed:
- 1. Upload grant — permissions
1,2,3 (Read+Write+List) for S3 upload - Website grant — permissions
1,3 (Read+List only) for website creation
Upload grant:
CODEBLOCK6
Website grant:
CODEBLOCK7
Output (single JSON line to stdout):
CODEBLOCK8
Parse JSON to extract UPLOAD_GRANT and WEBSITE_GRANT.
IMPORTANT: Website API rejects grants with Write (2) or Delete (4) permissions.
Alternative: config file
CODEBLOCK9
CLI flags
| Flag | Required | Description |
|---|
| INLINECODE146 | Yes | INLINECODE147 or INLINECODE148 |
| INLINECODE149 |
Yes | Root ZKey (base64url) |
|
--account | Yes | Account UUID |
|
--url | No | Service URL (default:
w3s) |
|
--duration | No | ms, 0 = no expiry (default:
0) |
|
--bucket | per-bucket | Bucket name |
|
--passphrase | Yes | 12-word seed phrase |
|
--permissions | per-bucket |
1,2,3,4 (1=Read 2=Write 3=List 4=Delete) |
|
--config | No | Path to JSON config file |
|
--output | No |
json for JSON output |
|
--quiet | No | Suppress logs, stdout only |
STEP 7: REGISTER S3 CREDENTIALS
Use the upload grant (permissions 1,2,3):
CODEBLOCK10
Extract: ACCESS_KEY_ID = data.access_key_id, SECRET_KEY = INLINECODE166
STEP 8: UPLOAD FILES TO S3
S3 endpoint: https://s3.aiozstorage.network | Region: us-east-1 | PathStyle: INLINECODE169
Using AWS CLI
CODEBLOCK11
Using Node.js (@aws-sdk/client-s3)
Use
S3Client with
{ region: "us-east-1", endpoint: "https://s3.aiozstorage.network", forcePathStyle: true, credentials: { accessKeyId, secretAccessKey } }.
Upload each file with
PutObjectCommand, setting correct Content-Type:
INLINECODE173 →text/html .css→text/css .js→application/javascript .json→application/json .svg→image/svg+xml .png→image/png .jpg/.jpeg→image/jpeg .webp→image/webp .ico→image/x-icon .md→text/markdown .woff2→font/woff2 default→ INLINECODE195
STEP 9: CREATE STATIC WEBSITE
Use the website grant (permissions 1,3 — Read+List only):
CODEBLOCK12
IMPORTANT: Website API rejects grants with Write (2) or Delete (4) permissions. Use --permissions 1,3 for this grant.
API domain is api.aiozstorage.app (not .network).
STEP 10: DONE
Site is live at: INLINECODE199
API DOMAINS
- -
api.aiozstorage.network — login, zkeys - INLINECODE201 — S3 credential registration
- INLINECODE202 — S3 upload endpoint
- INLINECODE203 — static website creation
- INLINECODE204 — static website URL
ERROR HANDLING
- - Login fails → check email/password
- ZKey creation fails → Bearer token expired, re-login
- Grant generation fails → verify rootZKey, accountId, bucket name, passphrase
- S3 upload fails → check credentials, endpoint, bucket name
- Website creation fails → check grant, bucket name, Bearer token
- Site 404 → ensure index.html at bucket root (not in subfolder)
IMPORTANT NOTES
- -
grant encodes both authorization (Macaroon/ZKey) and encryption key (EKey from passphrase) - Two grants needed: upload grant (permissions 1,2,3) and website grant (permissions 1,3)
- Website API rejects grants with Write (2) or Delete (4) permissions
- AIOZ Storage is S3-compatible — any AWS SDK works
- Bearer tokens expire — re-login on 401
- grant-cli.ts requires Node.js >= 18
- argon2-browser WASM loading is auto-patched in the CLI
- All template asset paths are relative (
./assets/...) — works from any base URL - For documents template, content is in
/docs/*.md with YAML front matter - For landing/landing-alt/portfolio, all content is in CONFIG object in INLINECODE208
AIOZ 静态网站部署
将静态网站部署到AIOZ去中心化存储。支持4个内置模板或用户自己的静态网站。
流程概览
- 1. 登录(邮箱 + 密码)→ Bearer令牌 + 账户ID
- 选择模板或自定义网站
- 克隆模板并自定义配置
- 获取存储桶信息(名称 + 12词助记词)
- 从API获取rootZKey
- 通过grant-cli.ts生成授权
- 从授权注册S3凭证
- 上传文件到S3
- 通过API创建静态网站
- 网站上线:https://.sites.aiozstorage.app
步骤1:登录
询问用户的AIOZ Storage邮箱和密码。
bash
curl -s https://api.aiozstorage.network/api/v1/login \
-H accept: application/json \
-H content-type: application/json \
-H origin: https://aiozstorage.network \
-H referer: https://aiozstorage.network/ \
--data-raw {email:,password:}
响应:data.access_token(Bearer令牌),data.account.id(账户ID)。
保存BEARERTOKEN和ACCOUNTID。
步骤2:选择模板
询问用户选择哪个模板,或者是否使用自己的静态网站。
模板来自 https://github.com/AIOZStorage/aioz-storage-docs/tree/main/examples:
- 1. landing — OLED暗色主题,X/Twitter风格着陆页。配置在assets/main.js中。
- landing-alt — 紫色渐变着陆页。配置在assets/main.js中。支持标题中的斜体渐变文字。
- portfolio — 面向开发者/设计师的简洁极简作品集。配置在assets/main.js中。项目图片轮播。
- documents — 完整的Markdown内容文档网站。配置在assets/js/config.js中。支持搜索、目录、语法高亮。
- 自定义 — 用户提供自己的静态文件。
步骤3:克隆模板并自定义
克隆所选模板:
bash
git clone --depth 1 https://github.com/AIOZStorage/aioz-storage-docs.git /tmp/aioz-storage-docs
cp -r /tmp/aioz-storage-docs/examples/name> ./folder>
然后根据模板类型自定义CONFIG对象:
模板:landing
配置:assets/main.js → CONFIG对象。主题:dark(OLED黑色)或light。
需要自定义的关键字段:
- - brand.name — 品牌/产品名称
- meta.title,meta.description — SEO
- hero.eyebrow — 徽章标签(或设为null隐藏),hero.title,hero.sub
- hero.primaryCta — { label, href },hero.secondaryCta
- sections.* — 开关:highlights,logos,features,useCases,testimonials,pricingTop,pricingBot,faq
- highlights[] — { number, label }统计数据(数字在滚动时动画显示)
- logos.items[] — 公司名称字符串
- features — { label, title, sub, items: [{ title, desc }] }
- useCases — { label, title, sub, items: [{ tag, title, desc }] }
- testimonials[] — { quote, name, role, company, avatar: { initials, bg } }
- pricing.plans[] — { name, price, period, desc, isPopular, cta: { label, href }, features[] }
- faq.items[] — { q, a }
- cta.form.mode — redirect | mailto | webhook
- footer.brandDesc,footer.columns[],footer.socials[]
- assets/style.css中的颜色 :root → --color-primary: #1d9bf0
模板:landing-alt
配置:assets/main.js → CONFIG对象。主题:light | dark | system。
需要自定义的关键字段:
- - brand.name,brand.tagline
- hero.badge — 徽章标签(或设为null),hero.headline(用星号包裹单词实现渐变斜体文字),hero.subheadline
- hero.primaryCta,hero.secondaryCta,hero.ctaNote
- sections.* — 开关:stats,problemSolution,features,useCases,logos,testimonials,pricing,faq
- stats[] — { number, label }(数字在滚动时动画显示)
- problemSolution — { problem: { label, title, items[] }, solution: { label, title, items[] } }
- features.items[] — { size, gradient, kicker, title, desc, tag, visual }(bento网格,size:wide|narrow|half|third|full)
- pricing.plans[] — { name, price, period, desc, isPopular, cta, features[] }
- cta.form.mode — redirect | mailto | webhook
- assets/style.css中的颜色 → --color-primary: #635bff,--color-gradient-start,--color-gradient-end
模板:portfolio
配置:assets/main.js → CONFIG对象。主题:light | dark | auto。
需要自定义的关键字段:
- - personal.firstName,personal.lastName,personal.title,personal.email
- personal.location — { city, country }
- about.subtitle,about.bio(段落数组),about.focusAreas(技能字符串数组)
- experience[] — { company, tagline, period, position, description, longDescription, location, industry, website: { label, url } }
- projects[] — { title, tags[], year, images[], description, techNote, link: { label, url } }(多张图片=轮播)
- social[] — { platform, url }
- theme.defaultMode,theme.showToggle
- sections — 开关:showAbout,showExperience,showProjects,showFocusAreas
- footer.cta,footer.copyright(null=自动生成)
- meta.title,meta.description,meta.ogImage
- assets/images/中的图片(项目图片1600×900,OG图片1200×630)
模板:documents
配置:assets/js/config.js → CONFIG对象。主题:light | dark | auto。
需要自定义的关键字段:
- - site.title,site.description,site.version
- site.logo.light,site.logo.dark
- sidebar[] — { group, collapsed, items: [{ label, path }] }(path = 不带.md的文件名)
- header.nav[] — { label, href },header.links[] — { icon, href }
- footer.copyright,footer.columns[]
- features — 开关:search,tableOfContents,feedback,prevNext,copyCodeButton,scrollToTop
- features.editLink — { enabled, baseUrl, text }
- features.tocDepth — 2或3
内容:在/docs/中创建带YAML前置元数据的.md文件:
yaml
title: 页面标题
description: 简要描述
order: 1
hidden: false
标注:> [!NOTE],> [!TIP],> [!WARNING],> [!DANGER]
带语法高亮的代码块(javascript,typescript,python,bash,json,html,css,yaml,sql,go,rust,java等)
哈希路由:index.html#/page-name → 加载docs/page-name.md
步骤4:获取存储桶信息
询问用户:
- 1. 存储桶名称 — 他们在aiozstorage.network上的存储桶
- 12词种子