# Deploy KitJS on a static website

A static website can use KitJS directly from one exact CDN script. It does not
need a frontend compiler, runtime package loader, Go process, or application
server.

This checkout targets the stable `1.0.0` browser artifacts. Public npm/CDN
availability and npm `latest` resolution are recorded separately after
independent retrieval.

For a quick experiment, `https://cdn.jsdelivr.net/npm/@kitwork/kitjs` follows
npm `latest` and may be automatically minified by jsDelivr. It upgrades
automatically, so do not reuse the readable `dist/kit.js` SRI with that bare
URL. Production pages should pin an exact file and matching SRI.

## 1. Choose one exact CDN profile

Use Kit when navigation should remain completely browser-native:

```html
<script
  defer
  src="https://cdn.jsdelivr.net/npm/@kitwork/kitjs@1.0.0/dist/kit.js"
  integrity="sha256-LXt1DK4QG43susUNwzTQp7H046G1/gONdOhBAcXVIZI="
  crossorigin="anonymous"></script>
```

Use Hydrate when eligible same-origin links and GET forms may use
compatibility-checked Drive/Morph:

```html
<script
  defer
  src="https://cdn.jsdelivr.net/npm/@kitwork/kitjs@1.0.0/dist/hydrate.kit.js"
  integrity="sha256-AbI+PkXOVgSxZDNiMjQCxehrcASWQuW+mJHrSmfS57k="
  crossorigin="anonymous"></script>
```

Hydrate contains the complete Kit runtime. Never load both profiles on one
page. Hydrate incompatibility falls back to normal document navigation before
the current document is mutated.

The exact deterministic identities in this checkout are:

| Profile | Bytes | SHA-256 | SRI |
|---|---:|---|---|
| Kit | 206,607 | `2d7b750cae101b8decbac50dc334d0a7b1f4e3a1b5fe038d74e84101c5d52192` | `sha256-LXt1DK4QG43susUNwzTQp7H046G1/gONdOhBAcXVIZI=` |
| Hydrate | 314,424 | `01b23e3e45ce5604b1643362323402c5e86b70049642e5be9891eb4a67d2e7b9` | `sha256-AbI+PkXOVgSxZDNiMjQCxehrcASWQuW+mJHrSmfS57k=` |

These local identities do not by themselves establish public availability.
The immutable `1.0.0-rc.2` publication evidence and the eventual stable public
verification are recorded in [`RELEASE_READINESS.md`](RELEASE_READINESS.md).

## 2. Add ordinary HTML

No application root or registration step is required for local state:

```html
<section data-kit-scope="count: 0; open: true">
  <button type="button" data-kit-click="count++">Increment</button>
  <output data-kit-text="count">0</output>
  <button type="button" data-kit-click="open = !open">Toggle</button>
  <p data-kit-if="open">This branch is mounted.</p>
</section>
```

Keep real fallback text and semantic HTML in the document. KitJS enhances that
HTML after the deferred script is ready.

## 3. Optional self-hosting

CDN delivery is the simplest path. A site that requires same-origin assets may
instead download the exact verified profile file and serve it locally. Compare
the downloaded byte length and SHA-256 with the table above before deployment.

Use an immutable versioned or content-hashed filename:

```html
<script
  defer
  src="/assets/kit.1.0.0.2d7b750cae101b8d.js"
  integrity="sha256-LXt1DK4QG43susUNwzTQp7H046G1/gONdOhBAcXVIZI="></script>
```

Never replace bytes behind an immutable URL. A changed file needs a new URL,
SRI value, and coordinated HTML release.

The packaged `dist/integrity.json` uses a deterministic schema containing the
package/version, filename, bytes, SHA-256, and SRI for both profiles. It has no
timestamp or machine path and can be used to verify a self-hosted copy.

## 4. Optional standalone components

The CDN profiles support direct client registration with an unversioned name.
Put trusted component definitions in an external file:

```html
<nav data-kit-component="site-menu">
  <button type="button" data-kit-click="toggle()">Menu</button>
  <div data-kit-show="open">...</div>
</nav>

<script
  defer
  src="https://cdn.jsdelivr.net/npm/@kitwork/kitjs@1.0.0/dist/kit.js"
  integrity="sha256-LXt1DK4QG43susUNwzTQp7H046G1/gONdOhBAcXVIZI="
  crossorigin="anonymous"></script>
<script defer src="/assets/components.js"></script>
```

```js
// /assets/components.js
kit.component("site-menu", {
  open: false,
  toggle() {
    this.open = !this.open;
  }
});
```

The runtime and later deferred registration file keep their authored order and
finish before the first component audit. Component definitions are trusted page
JavaScript. Do not register untrusted source.

The standalone package does not use versioned component hosts.
`data-kit-version` is unsupported, and there is no `data-kit-local` marker.

## 5. Hydrate-compatible route groups

For Drive to preserve one live document, the current and incoming pages must
have the same executable script topology:

- Hydrate is a classic external `defer` script and a direct child of `head`;
- its resolved URL, direct-head position, order, and complete attributes are
  identical on every compatible page;
- every other executable script that must persist follows the same rules;
- cross-origin scripts use valid SRI and omit `data-kit-drive="stable"`.

The exact jsDelivr Hydrate tag in section 1 already supplies cross-origin SRI.
Copy that complete tag unchanged to every page in the compatible route group.

For a self-hosted same-origin external script, the exact
`data-kit-drive="stable"` marker may be used as an author promise:

```html
<script
  defer
  src="/assets/hydrate.kit.1.0.0.js"
  data-kit-drive="stable"></script>
```

`stable` is not a content check. The site promises not to change the URL,
bytes, position, order, or attributes independently. Prefer a content-hashed
URL plus SRI when practical.

Inline scripts, body scripts, modules, import maps, speculation rules,
`async`, `nomodule`, unknown script policy, or an added, removed, reordered, or
changed executable script are incompatible. Hydrate then leaves navigation to
the browser before changing the live document. It never inserts or runs scripts
found in fetched HTML.

An inline `kit.component(...)` registration therefore works with the Kit
profile but intentionally keeps Hydrate navigation native. For Drive-compatible
components, use one external registration file with the same exact tag on all
compatible routes.

Use `data-kit-drive="false"` on a link, GET form, submitter, or ancestor that
must always navigate normally.

Hydrate also falls back when a usable response exceeds 8 MiB, a parsed document
has more than 100,000 nodes, or its depth exceeds 256. Same-document fragment
links remain browser-native. Compatible cross-route navigation preserves the
requested fragment, focus, scroll, forms, history, and component cleanup under
the browser contract.

The advanced [`examples/static-hydrate`](examples/static-hydrate/README.md)
site demonstrates a compatible group and one intentional native boundary.

## 6. Cache and response headers

Recommended caching:

| Resource | Cache policy |
|---|---|
| HTML | Revalidate, or use a short deployment-controlled lifetime |
| Exact-version CDN script | Follow the CDN's immutable exact-version policy |
| Self-hosted versioned/content-hashed script | `public, max-age=31536000, immutable` |

Serve self-hosted JavaScript as `text/javascript` or
`application/javascript`, add `X-Content-Type-Options: nosniff`, and enable
Brotli or gzip transport compression.

A CSP response header from an incoming fetched page cannot be applied to the
already-live document. Hydrate therefore treats a destination with such a
header, or an incompatible CSP declaration, as a native-navigation boundary.
Keep required response headers and accept native fallback; never weaken a CSP
merely to retain Morph continuity.

A static route group may instead author the same CSP meta declaration on every
page when that policy is appropriate:

```html
<meta
  http-equiv="Content-Security-Policy"
  content="default-src 'self'; script-src 'self' https://cdn.jsdelivr.net; object-src 'none'; base-uri 'none'">
```

If the site uses the cross-origin CDN tag, its CSP must allow that exact script
origin. CSP design remains the site's responsibility.

## 7. Subpath deployments

For a site deployed below a prefix such as `/docs/`, use the same absolute
prefixed URLs on every compatible page:

```html
<script defer src="/docs/assets/hydrate.kit.1.0.0.js" integrity="sha256-AbI+PkXOVgSxZDNiMjQCxehrcASWQuW+mJHrSmfS57k="></script>
```

Do not mix route-relative forms such as `../assets/...` and `./assets/...`.
Drive compares resolved script identity and ordered attributes.

## 8. Production checklist

1. Use exactly one profile and pin `1.0.0`.
2. Preserve the exact CDN URL, SRI, and `crossorigin="anonymous"` attributes.
3. Open every route while collecting JavaScript errors.
4. If using Hydrate, verify the intended route group Morphs and a deliberately
   incompatible destination performs native navigation.
5. Test redirects, Back/Forward, fragments, focus, GET forms, and component
   cleanup.
6. Test every browser/version the website claims to support.
7. Keep secrets and authorization decisions out of client-authored HTML.

Release verification and source-building commands are maintainer concerns; see
[`BUILDING.md`](BUILDING.md) and
[`RELEASE_READINESS.md`](RELEASE_READINESS.md) rather than adding them to a
static site's deployment workflow.
