Version History
Snapshot template state at any point and roll back to it byte-for-byte. Stores immutable copies of content, form schema, variables, and metadata.
Version History
Crove templates are live-edited and auto-saved. Sometimes you want a checkpoint — "this is the version we sent to the client", "this is the one before I tried that risky refactor". Version history lets you snapshot the template at any moment and restore to that snapshot later.
Snapshots are immutable — once captured, they cannot be edited. Restoring brings the live template back to that exact state without touching the snapshot itself.
Opening version history
In the template editor toolbar, click the History icon (clock arrow). The dialog opens with two areas:
- New snapshot composer at the top — capture the current state
- Version list below — newest first, with timestamps and change notes
Capturing a snapshot
- (Optional) Type a change note — what's interesting about this point in time? "Pre-launch review", "Client requested wording change", etc. Up to 200 characters.
- Pick a version bump — Patch / Minor / Major (semver):
- Patch — small tweaks, default
- Minor — meaningful new field or section
- Major — significant rework, possibly breaking
- Click Snapshot
Crove bumps template.version (e.g. 1.0.0 → 1.0.1 for patch),
copies the current S3 content + form schema to versioned keys
(templates/{id}/versions/{versionId}/…), and inserts a row in
template_version. The new version appears at the top of the list.
The current version shows as a current vX.Y.Z badge in the
composer header.
Restoring a snapshot
- Find the version in the list
- Click Restore
- Confirm in the alert dialog
Crove copies the snapshot's S3 objects back to the live template's S3
key, replaces the symbol table / expression table / roles / metadata
inline, and bumps the live template.version to match. The page
reloads so the editor re-hydrates with the restored content.
Why your restore actually works (vs other versioning systems)
Earlier in development we found a bug where restores were no-ops
because the snapshot stored the same S3 sentinel as the live
template — every later edit overwrote the snapshot's content too. The
fix copies S3 objects to versioned keys
(templates/{id}/versions/{versionId}/content.json) so snapshots are
truly immutable. Restoring copies that versioned object back to the
live key. End-to-end verified: a 14,466-byte template snapshotted,
mutated to 192 bytes, then restored — comes back byte-identical.
What's captured in a snapshot
| Captured | Notes |
|---|---|
| Editor content | The full Plate.js document |
| Form schema | Sections + pages + display rules |
| Symbol table | All variables (form fields + named expressions) |
| Expression table | Computed expression source code |
| Roles | Multi-party signing setup |
| Metadata | Page settings, tags, archived state, etc. |
Not captured (these are live state, not template state):
- Documents created from the template
- Public-link config (intentional — restore shouldn't accidentally re-publish or change passwords)
- Webhook configuration
When to snapshot
- Before risky refactors — "I'm about to delete a bunch of variables, snapshot first"
- At meaningful milestones — "v2.0.0 — went live with the new rate card"
- Before delegating to a teammate — "snapshot before handoff so I can recover if needed"
- Around legal or contract changes — keep an audit trail of exactly what wording was active when
Tips
- Change notes are searchable in your head — write them as if you'll read them in 6 months. "Patch" alone is useless; "Patch: fixed typo in payment terms" is useful.
- Major bumps are forever — Crove never garbage-collects snapshots, but you can mentally treat major bumps as the long-term anchors and patches as scratch.
- Restore doesn't delete other snapshots — restoring to v1.0.5 doesn't drop v1.0.6 or v1.0.7. They all stay in history; the live template just rewinds.
- You can always re-snapshot before restoring — habit: capture the current state first, then restore. That way you can roll forward again if the restore wasn't what you wanted.