gitqi

GitQi 气

Get the key to your own website.

A zero-dependency, browser-based inline editor for static HTML. Click any text, swap any image, reformat a section with AI, and publish straight to GitHub Pages — no terminal, no CMS, no subscription.


Why

Most website tools rent you an experience. GitQi gives you back the page.

GitQi has two modes:


Two paths


🔑 The Get Key path

Seven steps. No installs, no terminal. Works on any machine with Chrome or Edge.

1. Design your site prompt

Open the Bootstrap Prompt. Fill in the bracketed fields (name, tagline, sections, vibe) and gather 2–5 inspiration images. Paste the prompt into Claude.ai (a free account works), attach your images, and save the output as index.html in a new folder on your computer (e.g. my-site/).

The AI-generated HTML is a starting point, not a final product. You’ll edit every word of it directly on the page once GitQi is running. Focus the prompt on establishing a theme and structure you like — don’t try to get the copy perfect.

2. Create a GitHub repository

Create a new public repository on GitHub (e.g. jane/jane-osteopathy). Leave it empty — don’t add a README, .gitignore, or license. GitQi will populate it on first publish.

You do not need to enable GitHub Pages yet. That step comes last (Step 7), after your first publish creates the main branch. Trying to enable Pages on an empty repo with no branch to serve from will just fail.

3. Create a GitHub access token

Profile photo → Settings → Developer settings → Personal access tokens → Fine-grained tokens → Generate new token.

Generate, then copy the token immediately (GitHub only shows it once). It starts with ghp_.

This token can only read and write files in your one repository. It cannot access your GitHub account or any other repo. If it’s ever exposed, revoke it and generate a new one in seconds.

4. Get a free Gemini API key

Go to aistudio.google.com, sign in with any Google account, and click Get API key → Create API key. Copy the key (starts with AIza). No billing, no credit card, no Cloud Console configuration.

If you get prompted to enable billing, you’re in the wrong place — step back from Google Cloud Console to AI Studio itself.

If AI actions fail with “model is busy” or “quota exceeded”: GitQi auto-fallbacks across Gemini models (2.5 Flash → 2.5 Pro → 2.0 Flash → Flash latest → 2.5 Flash Lite) on retryable errors. Each model has its own independent quota on AI Studio, so a daily-limit hit on one doesn’t block the others. You’ll see a status message when a fallback kicks in. If all models fail in one request, the error dialog exposes a Retry with model dropdown so you can pin a specific one.

5. Create secrets.js

In the same folder as your index.html, create a plain-text file named secrets.js:

// secrets.js — lives beside your HTML, never published
window.SITE_SECRETS = {
  geminiKey: "AIza...", // your Google AI key (Step 4)
  githubToken: "ghp_...", // your GitHub token (Step 3)
  repo: "username/my-site", // your GitHub user / repo name
  branch: "main",
};

Your folder now looks like:

my-site/
├── index.html
└── secrets.js          ← stays on your machine, forever

secrets.js is never pushed to GitHub. GitQi strips it (and gitqi.js) from the published output on every publish. Credentials never leave your computer.

6. Edit and publish

Open index.html in Chrome or Edge (drag it into a browser window, or right-click → Open With). The GitQi toolbar appears automatically.

A banner appears prompting you to Select Folder — pick the folder containing your HTML. This links GitQi to your files so every edit auto-saves within ~1.5 seconds. The link persists across sessions (one permission prompt per session).

Edit anything:

When you’re ready, click Publish in the toolbar. GitQi strips all editor code + secrets.js, serializes the clean HTML, and pushes it to GitHub via the Contents API. That first publish also creates the main branch — which is what Step 7 needs.

Safari and Firefox are not supported. Editing requires the File System Access API, which only Chromium browsers ship today. The published site itself works in every browser.

7. Turn on GitHub Pages

In your repo on GitHub: Settings → Pages → Source → Deploy from a branch. Set branch to main, folder to / (root), click Save.

GitHub shows a banner: “Your site is live at https://your-username.github.io/your-repo-name/”. The first deploy takes about a minute.

🎉 You’re in. From here on, the loop is: open index.html, edit, click Publish. No terminal, no git, no CMS, no monthly bill.


Editing reference

Text — click any data-editable element and type directly.

Text formatting — select text to reveal a floating toolbar. Buttons: B (bold), I (italic), 🎨 (color — theme swatches, custom picker, or remove), Aa (font — theme font vars or clear), A↕ (font size — em-relative presets from Smaller to Huge), </> (inline code), 🔗 (link).

Links — click any link (body or nav) to open the popover. Fields: display text, URL, Go to link → (preview), page/section picker (jumps to any page or #anchor across your site), open-in-new-tab toggle, remove-link.

Images — click any data-editable-image element to replace it. The file is written to your local assets/ folder and queued for GitHub upload on the next publish.

Sections

Navigation — hover the nav → ⟳ Reformat Nav (AI restructure). Changes sync to every other page automatically.

Pages (multi-page sites) — click Pages in the toolbar. Navigate between pages, generate a new AI page, or delete a page. New page links are added to the nav and propagated to every page.

AI model fallback — all four AI actions (Add Section, Reformat, Reformat Nav, Add Page) route through a fallback chain of Gemini models. If the primary is overloaded or rate-limited, GitQi automatically retries on the next one and shows a status like “Using Gemini 2.5 Pro — primary model was busy”. On total failure the error dialog offers a Retry with model dropdown so you can force a specific model.

Theme — click Theme for live controls over:

Undo / Redo — toolbar / buttons, or Ctrl+Z / Ctrl+Shift+Z. Covers structural changes (AI actions, section/page deletes). Text edits use the browser’s native undo.


HTML data attributes

GitQi uses data attributes to identify editable regions. The AI-generated HTML includes them automatically; if you’re hand-authoring, here’s the reference.

Attribute Applied to Purpose
data-zone <section> Marks a top-level editable section. Value is a slug, e.g. "hero". Also used as the element id for anchor links.
data-zone-label <section> Human-readable label shown in the delete confirmation, e.g. "Hero".
data-editable Any text element Makes the element directly editable via contenteditable.
data-editable-image <img> Makes the image replaceable by clicking.

Minimal example:

<section data-zone="about" data-zone-label="About">
  <h2 data-editable>About Me</h2>
  <p data-editable>Replace this with your own text.</p>
  <img src="./assets/placeholder.jpg" data-editable-image alt="Profile photo" />
</section>

Script tags

Two script tags must appear in <head> (after the <style> block) for edit mode to work locally. Both are stripped automatically on export and publish — the deployed site contains neither.

<script src="./secrets.js"></script>
<script src="https://swill.github.io/gitqi/gitqi.js"></script>

Multi-page sites

Multi-page sites use a gitqi-pages.json manifest in the site folder alongside the HTML files:

{
  "pages": [
    { "file": "index.html", "title": "Home — My Site", "navLabel": "Home" },
    { "file": "about.html", "title": "About — My Site", "navLabel": "About" },
    { "file": "services.html", "title": "Services — My Site", "navLabel": "Services" }
  ]
}

GitQi creates and maintains this file automatically. It’s pushed to GitHub on every publish. Adding GitQi to an existing single-page site creates the manifest automatically the first time you link your folder.

Shared head + nav sync — on every auto-save, GitQi compares the current page’s shared elements against a snapshot from the last sync. If anything changed, the updated elements are written to every other page file on disk automatically.

Synced site-wide:

When the nav is synced, the “current page” highlight is re-targeted for each destination: the link matching that page gets the active marker; every other link is cleared. Recognised markers are the aria-current attribute and the CSS classes active, current, is-active, is-current, and selected.

Left page-specific: <title>, <meta name="description">, <meta name="keywords">.


Custom domain (optional)

By default your site is served at https://username.github.io/repo-name. To use your own domain (e.g. www.janeosteopathy.com):

Option A — Subdomain (www or any prefix) — CNAME record

  1. In your DNS provider, add a CNAME record: | Name | Type | Value | |—|—|—| | www | CNAME | username.github.io |
  2. In your GitHub repo, Settings → Pages → Custom domain, enter www.example.com, click Save. GitHub creates a CNAME file automatically.
  3. Check Enforce HTTPS once the certificate is provisioned (usually a few minutes).

GitQi publishes by overwriting HTML files only — it doesn’t touch the CNAME file. Your custom domain stays configured across all publishes.

Option B — Apex domain (no www) — A records

  1. In your DNS provider, add four A records: | Name | Type | Value | |—|—|—| | @ | A | 185.199.108.153 | | @ | A | 185.199.109.153 | | @ | A | 185.199.110.153 | | @ | A | 185.199.111.153 |
  2. Optionally add a CNAME for wwwusername.github.io so both work.
  3. In your GitHub repo, Settings → Pages → Custom domain, enter example.com, click Save.
  4. Check Enforce HTTPS once the certificate is provisioned.

DNS changes can take up to 48 hours to propagate. GitHub will warn you if the domain isn’t verified yet — wait a few minutes and refresh.


气 The Git Qi path — advanced

You have the key. Now the Qi: how GitQi actually works, how to pin or self-host gitqi.js, and how to cut your own releases.

How it works

GitQi is a single JavaScript file that activates only when window.SITE_SECRETS is set (i.e. when secrets.js has loaded). In public mode the script tag is stripped entirely, so there’s nothing to load and nothing to run.

The publish pipeline is:

  1. Serialize the live DOM (clone, strip editor UI, resolve local image paths).
  2. Strip the editor and secrets.js script tags.
  3. Push each page via the GitHub Contents API (PUT /repos/{repo}/contents/{path}).
  4. GitHub Pages serves the updated file within ~60 seconds.

No git on your machine, no CI, no build step. The HTML is the artifact.

Hosting gitqi.js

gitqi.js is served from its own GitHub Pages repo so multiple sites can share a single hosted copy.

Latest version (always current):

https://swill.github.io/gitqi/gitqi.js

Pinned version (recommended for production — immune to upstream changes):

https://swill.github.io/gitqi/gitqi-<VERSION>.js

Pinned versioned files are committed alongside gitqi.js on each release and are never modified after publishing.

Fork and self-host

Want to own the whole stack?

  1. Fork swill/gitqi on GitHub.
  2. Enable GitHub Pages on your fork (Settings → Pages → Deploy from a branch → main / (root)).
  3. Change the script tag in your site’s HTML from swill.github.io/gitqi/gitqi.js to your-user.github.io/gitqi/gitqi.js.

You now run your own copy. Pin it, patch it, release on your own schedule.

Versioning

Versions follow Semantic Versioning:

The version is accessible at runtime:

console.log(window.GitQi.version);

Development

# Local development server (http://localhost:8080, CORS enabled)
make serve

# Check JavaScript syntax
make check

# Release a new version — writes gitqi-<VERSION>.js, bumps VERSION, tags, pushes
make release VERSION=1.3.0

# Regenerate the Google Fonts manifest (google-fonts.json)
make fonts

See the Makefile for the full details of what each target does.

Google Fonts manifest

GitQi ships a full Google Fonts catalog (google-fonts.json, served alongside gitqi.js) so the font picker covers the entire library, not just a curated subset. The manifest is regenerated manually via make fonts. At runtime gitqi.js fetches it, caches it in localStorage, and falls back to a small built-in list if the fetch fails.

One-time setup — needed only if you want to regenerate the manifest yourself:

  1. Get a free Google Fonts Developer API key:
    • Go to the Google Cloud Console
    • Create (or pick) a project
    • Enable the Web Fonts Developer API under APIs & Services → Library
    • Create a key under APIs & Services → Credentials → Create Credentials → API key
    • Restrict it (recommended): under API restrictions pick Web Fonts Developer API only
  2. Copy the example file and drop your key in:
    cp .env.example .env
    # then edit .env and set GOOGLE_FONTS_API_KEY=<your-key>
    

    .env is gitignored — the key never lands in the repo.

  3. Generate the manifest:
    make fonts
    

    This fetches the catalog from the Developer API, sorted by popularity, and writes google-fonts.json at the repo root — each entry is { name, cat, weights }. Array order is the popularity ranking. Commit the file and it deploys alongside gitqi.js on the next release.

Contributing

The source is yours to read, fork, and improve. Issues and pull requests welcome at github.com/swill/gitqi.


Security notes


Compatibility

Browser Edit mode Public site
Chrome 86+
Edge 86+
Safari
Firefox

Edit mode requires the File System Access API. The published site is plain HTML and works everywhere.


License

MIT. Free, forever.