Skip to Content
DocumentationTemplate Upgrades

Template Upgrades

An app copied from a template normally drifts away from it forever: the template improves, the copy never hears about it. Template upgrades fix that. A copied app can notice “the original got a new version,” and one click pulls in the new design while pouring your existing data into it.

The whole mechanism is client-side: download the new file, move your labeled data in, save. No server endpoint, no registry, no account linking.

Opting in: two meta tags

A page becomes upgradable when it carries two meta tags:

<meta name="hyper-source" content="https://devlog.panphora.hyperclay.com"> <meta name="hyper-version" content="1.2.0">
  • hyper-source is the address of the canonical version, the page this one was copied from. It doubles as identity: there is no separate registry.
  • hyper-version is a dotted version number, compared numerically (1.10 is newer than 1.9).

Template authors set these once. Copies inherit them automatically, because copying the HTML copies the tags. A page whose hyper-source points at itself is the canonical version and never sees an upgrade prompt.

What owners see

Once a day, when the owner opens their app in edit mode, it quietly fetches the original and compares version labels. If the original is newer, a small card appears in the corner:

Update available v1.0.0 → v1.2.0 from: https://devlog.panphora.hyperclay.com  Your current version is kept in version history. Customizations outside your data will be replaced.

[Upgrade] [Later] [Skip this version]

Visitors never see it, only the owner in edit mode. “Skip this version” remembers the choice until the next version ships. Every upgrade saves through the normal pipeline, so the pre-upgrade page sits in version history, one restore away.

What carries over

Your app’s data layer is its rules tags: named maps from field names to CSS selectors. The upgrade packs your current data into labeled boxes (one per rules tag), downloads a clean copy of the new template, and unpacks by matching labels:

  • Fields present in both versions carry over.
  • Fields the new version dropped are discarded, and counted, so the owner is told.
  • Fields the new version added keep the template’s defaults.
  • Your lists keep your item count: three projects in the old version means three projects in the new one.

The downloaded copy is parsed without running any of its scripts, so nothing about the template’s runtime state leaks into your saved file. Everything outside the data layer, layout, styles, scripts, becomes the new template’s version. That is the point of upgrading.

The migration recipe

When a new version renames or restructures fields, plain label-matching is not enough. The template author includes a recipe inside the template’s own HTML:

<script type="text/hyper-upgrade"> export default function upgrade(dataByName, { fromVersion, toVersion }) { return { api: { heading: dataByName.api.title, // v2 renamed "title" to "heading" posts: dataByName.api.posts, }, settings: dataByName.profile, // v2 renamed the "profile" rules tag } } </script>

Browsers ignore the unknown script type, so the recipe never runs on the template’s own page. The upgrading copy reads it out of the downloaded file and runs it exactly once, after the owner clicks Upgrade and before anything is saved. It receives all your data keyed by rules-tag name and returns the reshaped map. It can be async. If it throws, the upgrade aborts and nothing changes.

No recipe means plain label-matching, which is fine for most updates.

Making your template upgradable

  1. Add the two meta tags, with hyper-source pointing at your template’s own URL.
  2. Describe your data layer with rules tags, so copies know what counts as “their data.”
  3. Bump hyper-version whenever you publish a meaningful change.
  4. If a release renames or restructures fields, ship a text/hyper-upgrade recipe in the same release.

That’s all. The template needs no JavaScript support for upgrades; only the copy does. In HyperclayJS the upgrade module is included in the smooth-sailing and everything presets.

Notes

  • The version check runs at most once a day per app and caches the result. Owners can force one with hyperclay.upgrade.checkForUpdate({ force: true }).
  • If the source is unreachable or private, the check stays silent.
  • If the new version has no rules tags at all while your copy has data, the upgrade refuses rather than silently dropping everything.
  • Programmatic access: hyperclay.upgrade.run() performs the migration and returns the new HTML without saving, if you want to build your own flow.
Last updated on