Knowledge Base/How to backup up your Uniform project

How to backup up your Uniform project

how-toDeveloperCLIWebhooksCanvasContextSDKMaintenance

Backing up your Uniform project content is essential for preserving data and ensuring you can recover from unexpected issues. Maintaining copies of compositions, entries, and other content entities helps in scenarios such as accidental deletions, content corruption, or even broader incidents (e.g., infrastructure outages or similar disasters)​. By implementing a robust backup strategy, you gain the ability to perform point-in-time recovery of content, audit changes over time, and restore data in disaster recovery situations.

Uniform provides two primary methods for backing up content:

  • Automated incremental backups via Webhooks: Captures content changes in real-time as they happen.
  • Manual or scheduled full backups via the Uniform CLI: Exports the entire project state on demand for snapshot backups and allows restoring that state when needed.

In this article, we will explore both approaches in detail. The target audience is technical (developers or system admins), as the steps involve configuring webhooks, writing scripts, and using command-line tools rather than UI-only actions. We’ll also cover best practices like storing backups in version control (e.g. Git) for safe keeping and outline use cases where backups are invaluable for operational and disaster recovery.

Uniform Webhooks allow you to listen for events in your Uniform project and react by executing custom backup logic. In simple terms, a webhook is an event-driven HTTP request that Uniform sends to an endpoint you control whenever specific events occur​. By configuring webhooks for content changes, you can automatically capture updates and store them externally as a backup.

Uniform emits webhook events for various content types (compositions, entries, etc.) and actions (changes, deletions, publications). For backup purposes, the most important event types to listen for are those indicating content modifications or removals:

  • *.changed events: Triggered when content is created or updated. (Uniform uses "changed" to encompass both creation of new content and updates to existing content.) For example, composition.changed fires when a composition (page) is created or edited​, and entry.changed fires when a content entry is created/modified​.
  • *.published events: Triggered when content is published. For instance, composition.published fires when a composition is published (made live)​, and entry.published when an entry is published. Published events often indicate a content piece reached a final or live state.
  • *.deleted events: Triggered when content is deleted. E.g., composition.deleted when a composition is removed​, or entry.deleted for an entry deletion. Capturing deletions ensures your backup notes when content was removed (and you likely have the last known version from a prior changed/published event).

In addition to the above, Uniform projects may use pre-launch releases, which bundle content changes. If you use releases, you'll also want to listen for events in that context (they have their own event types, like composition.release.changed, composition.release.published, etc., which parallel the standard events but within a release). Similarly, other content-related entities have events we may want to capture:

  • Manifest published: The manifest.published event indicates a personalization manifest was published​. If your project uses Uniform personalization or testing, capturing this event can back up configuration or variant rules.
  • Project map changes: Project Maps define the URL structure of your project. Events like projectmap.updated (fires on creation or update of the map) and projectmap.node.inserted/updated/deleted correspond to changes in the URL structure​. Backing these up preserves your project's URL structure and hierarchy.
  • Redirects: If you manage redirect rules in Uniform, capture redirect.inserted, redirect.updated, and redirect.deleted events to back up those rules​.
  • Workflow transitions: The workflow.transition event fires when an item moves through a workflow stage​. While not directly content data, logging these can be useful for auditing content status changes. (The actual workflow definitions can be backed up via CLI, discussed later.)

All available event types are listed here. For practical backup implementation, focus on changed, published, and deleted events for compositions and entries (and their release variants), plus project map and redirect changes. These cover the creation, update, publishing, and deletion of the core content and structure in your Uniform project.

To set up automated backups, you'll create a webhook in Uniform and point it to an endpoint (a URL) that you control:

  1. Create a new Webhook Endpoint in Uniform: In your Uniform project settings, find the Webhooks section and add a new endpoint. Provide the target URL (where you will receive the HTTP POST requests).
  2. Select relevant event types: Specify which events should trigger the webhook. Initially, you might choose to receive all events (Uniform will send all if none are filtered), but it's best to select a subset to avoid noise​. For backup, include:
    • composition.changed, composition.published, composition.deleted
    • entry.changed, entry.published, entry.deleted
    • composition.release.changed, composition.release.published, composition.release.deleted (if using releases)
    • entry.release.changed, entry.release.published, entry.release.deleted (if using releases)
    • manifest.published
    • projectmap.updated, projectmap.deleted, projectmap.node.inserted/updated/deleted
    • redirect.inserted, redirect.updated, redirect.deleted
    • workflow.transition
  3. Save the webhook configuration. Uniform will start sending events to the endpoint when they occur.

Tip: If you don't have your endpoint ready yet, Uniform offers a testing tool via Svix Play (click "use Svix Play" in the endpoint setup) that generates a temporary URL to catch webhooks. This is useful for initial testing and inspecting event payloads.

Next, implement the receiving end – typically a small web service or cloud function that accepts the POST requests from Uniform. Each webhook call will contain a JSON payload describing the event and the entity affected. For example, a composition.changed payload includes details like the composition ID, name, and relevant URLs (API URL, editing URL, etc.)​. A simplified example payload for a composition change might look like:

{ "type": "composition.changed", "id": "0b9d2118-f2d0-4fe6-9d46-7c661abaf474", "name": "About Us", "project": { "id": "PROJECT_ID", ... }, "api_url": "https://uniform.app/api/v1/canvas?...&compositionId=0b9d2118-f2d0-4fe6-9d46-7c661abaf474&state=64", "edit_url": "https://uniform.app/projects/PROJECT_ID/dashboards/canvas/edit/0b9d2118-f2d0-4fe6-9d46-7c661abaf474", "initiator": { "name": "A User", "email": "user@example.com" }, "state": 64, "trigger": { "type": "manual" } }

In most cases, the webhook payload provides identifiers and links rather than the full content object. The api_url field is particularly useful: it’s an API endpoint you can call (authenticated with your Uniform API key) to fetch the full data of the entity that changed. In the example above, performing an HTTP GET on api_url would return the JSON definition of the "About Us" composition in state 64 (published state code).

Backup storage approach: When your webhook handler receives an event, your code should:

  • Verify the request is genuinely from Uniform (Uniform signs each webhook; you can validate using the signature as described in our docs​ to ensure authenticity).
  • Determine the event type and entity. For instance, if composition.changed or composition.published, fetch the latest composition JSON via the provided api_url (or via Uniform's API using the ID).
  • Save the retrieved content data to your backup store. This could be as simple as writing to a file system (e.g., saving a JSON file per composition or entry), or updating a record in a database. A common best practice is to integrate with a version control repository:
    • Commit to a Git repository: You can treat your content backups like code. For example, have a directory structure where each composition or entry has its own JSON/YAML file, or a timestamped folder for each event. On each webhook, update the relevant file and commit the change to a Git repo. Over time, this repo will contain the history of content changes, enabling point-in-time recovery by checking out an older commit.
  • Handle deletions appropriately: If you receive an *.deleted event, the content might no longer be available via the API. In this case, you should rely on the last backup you had for that item (from the previous change/publish event). You can mark the item as deleted in your backup store (or remove it, depending on your strategy). The important part is that you had captured its content before deletion. This underscores why listening to change and publish events (not just deletion) is critical to have a copy of content prior to removal.
  • Include other entities: For projectmap and redirect events, the payload might directly contain the data (like redirect URLs) or IDs to fetch via API. Make sure to also back up these configurations, as they are part of your "stack content" (defining site structure and redirects).

By setting up webhooks on create/update/delete events and writing scripts to store the webhook data in your own storage, you enable point-in-time recovery of your content. This automated approach ensures near real-time backups: any change an editor or developer makes in Uniform is captured externally within seconds. By storing each version of the content as it changes—ideally in a version-controlled system like Git—you can roll back to any previous state with confidence, minimizing the risk of data loss and enabling precise recovery when needed.

Note: Ensure your backup endpoint is robust and secure. Keep it protected (e.g., via a secret token or basic auth that Uniform includes in webhook calls) so only Uniform can send data. Log failures and use Uniform’s webhook retry capabilities if your endpoint is temporarily down. Uniform allows you to replay missed events from their dashboard if needed, so you can recover any lost webhook calls.

While webhooks provide continuous incremental backups, it's also important to take full snapshots of your Uniform project at regular intervals or before major changes. The Uniform CLI is a powerful tool that enables exporting (backup) and importing (restore) of all project data via command-line commands​. This is analogous to a manual or scheduled backup: you run a command to pull everything from Uniform into files, which you can store safely (and later push back to Uniform if recovery is needed).

First, install the Uniform CLI as per the official documentation (usually via npm, e.g., npm install -g @uniformdev/cli). Once installed, you can use the uniform command in your terminal.

The CLI organizes commands under categories. For backup/restore, the relevant commands are under uniform sync, which manages synchronization of project assets.

Before running a backup, you need to set up a configuration file for the CLI (commonly uniform.config.json or .ts). This file tells the CLI which entities to include and how to output the data. A minimal example configuration to enable backing up core content might look like this (in JSON format for simplicity):

{ "serialization": { "format": "json", "mode": "mirror", "directory": "./uniform-backup", "entitiesConfig": { "composition": {}, "component": {}, "entry": {}, "contentType": {}, "projectMapDefinition": {}, "projectMapNode": {}, "redirect": {}, "workflow": {} } } }

Explanation:

  • format: We choose "json" for the output format (the CLI also supports YAML if preferred).
  • mode: "mirror" means the pull will produce an exact mirror of the project state in the output directory (and a push would attempt to make the target project match the files exactly). Other modes like createOrUpdate or create are available, but mirror is useful for a full backup​.
  • directory: Where to store the serialized data. In this case ./uniform-backup (it could be a folder that will contain multiple files, or you could specify a single file path like data.json to put everything in one file​).
  • entitiesConfig: This is where we list all the entity types we want to include. We have added:
    • "composition" and "component" – these cover Uniform Canvas compositions (pages) and their components (the content building blocks inside compositions).
    • "entry" and "contentType" – if you're using Uniform's internal content management, these would include custom content types and entries. (Uniform can define content models and entries similarly to a CMS; if you're not using this feature, these might be empty, but including them ensures any structured content is backed up.)
    • "projectMapDefinition" and "projectMapNode" – these cover the project map (site structure). The definition is the overall map (like the root), and nodes are the pages/nodes within it.
    • "redirect" – your redirect rules.
    • "workflow" – any workflow definitions (stages and approvals flows you've configured for content governance).
    • (You could also include other entities such as personalization-related ones: e.g., "category", "signal", "test" for personalization categories, signals, A/B tests; or "asset" if Uniform manages assets. Include everything relevant to your project needs.)

This configuration file can be written in TypeScript or JSON. If using TypeScript, export the config object. The Uniform CLI will auto-discover uniform.config.* in the project root (or you can specify a config file with --config flag when running commands)​.

Once configured, you can perform a full backup by running the CLI pull command. In a terminal, navigate to your project (where the config file is), and run:

uniform sync pull

This will fetch all the configured entities from your Uniform project and save them to the local file system. Based on our config example, after running this, the ./uniform-backup directory will contain a structured set of JSON files representing your compositions, entries, project map, etc. Each entity type might be in its own subfolder or file as determined by the CLI's default for that type. For instance, you might see a compositions folder with a JSON file per composition, an entries folder, and so on, or a single data.json if configured that way.

The first time you run a pull, it effectively creates a full snapshot. If you run it again later, by default (mirror mode) it will update the local files to match the current state of Uniform (adding new files for new content, updating changed ones, and possibly deleting files for content removed in Uniform).

Storing the backup: After a successful uniform sync pull, you should take the output and store it securely. As recommended, use a version control system like Git to track these backup files. You can initialize a git repository in the uniform-backup directory and commit the files. For each subsequent backup, commit the changes. This practice yields a historical record of content changes. If needed, you can tag commits (e.g., "pre-launch backup April 2025") for important milestones.

Storing backups in Git (or another VCS) offers point-in-time snapshots. At any later date, you can retrieve the exact content state as of a given commit – useful if you need to audit changes or restore an earlier version of content. It also offloads storage to a reliable service (GitHub, GitLab, etc.) and benefits from their redundancy.

Alternatively, you could upload the backup files to cloud storage (like an AWS S3 bucket). The key is to have the backups in a separate system from Uniform itself.

You might automate the CLI backup on a schedule. For example, use a CI pipeline or a cron job to run uniform sync pull nightly or weekly, then push the backup to your repository. This scheduled backup complements the real-time webhook backups, giving you redundant safety nets (one captures every change live, the other captures the whole state at regular intervals).

In a scenario where you need to restore content (either to recover lost data or to clone data into another Uniform project), the CLI provides the counterpart command: uniform sync push. This reads the local serialized files and applies them to a target Uniform project, effectively importing the data.

Some use cases for uniform sync push (restore):

  • Disaster recovery: If your Uniform project data was lost or heavily corrupted, you could take the last good backup from Git, ensure the config covers what you need, and push it to the Uniform project (or even to a new project if starting fresh). This would recreate the compositions, entries, etc., as they were at backup time.
  • Environment migration or cloning: You might want to copy content from a production project to a development or staging project. By pulling from the source and pushing to the destination (using appropriate credentials/config for each), you can migrate content between projects.
  • Rollback to a point in time: If a large error was introduced and you need to revert to an earlier content state, you could checkout an older commit of your backup files (from Git) and run uniform sync push to apply that state back to Uniform. Caution: this might overwrite newer changes, so use carefully – often it's wise to push into a test environment first or communicate with your team.

To use uniform sync push, make sure your entitiesConfig in the config file is aligned with what you want to restore. If you only want to push certain entities, you can adjust the config or use flags to limit what gets imported. For example, perhaps you want to restore compositions and entries, but not overwrite redirects or not trigger certain workflows; the CLI config allows enabling/disabling push per entity​. In our earlier config, more entities were enabled for syncing.

Run the push with a similar command:

uniform sync push --config ./uniform-backup-config.json

(This assumes ./uniform-backup-config.json contains or points to the backup data you want to restore. Often, the same config used for pull can be used for push, pointing to the same directory of data.)

Important: Consider the push mode. In mirror mode, a push will try to make the Uniform project exactly match the files – which could delete content in Uniform that is not present in your backup files. That might be intended for a full restore scenario, but if you are merging content or only adding missing pieces, you might use a different mode (like createOrUpdate which adds new or updates existing content without deleting anything not in the backup). Always review the CLI documentation and perhaps test in a non-production environment first to ensure the push behaves as expected.

  • Use Version Control for Backups: As mentioned, storing backups in Git or another VCS provides both safekeeping and history. Commit your uniform sync pull outputs and consider using branches or tags for significant snapshots (e.g., a pre-deployment backup).
  • Secure the Backup Repository: If your content is sensitive, ensure your backup repository is private and access is restricted. Even though it's "just content", treat it with appropriate security. If committing to a public repo, review that you aren't exposing any credentials or proprietary information.
  • Regularly Test Restorations: A backup is only as good as your ability to restore it. Periodically test the uniform sync push process on a non-production Uniform project to verify that your backups can be applied cleanly. This also helps you familiarize with the process so that in an urgent situation, you're prepared.
  • Monitor Webhook and Backup Jobs: Set up monitoring or alerts for your webhook receiver (e.g., if any failures occur) and for scheduled CLI backup jobs. This ensures you catch issues early. Uniform’s webhook logs can be filtered by event type to debug if certain events are being sent​.
  • Combine Strategies: For comprehensive coverage, use both webhooks and periodic full exports. The webhooks give you granular, immediate backups of each change, while the full CLI exports give you a consistent snapshot of the whole project at intervals. The redundancy means even if a webhook was missed or a full backup hadn’t run before an incident, the other method might save the day.
  • Retention and Cleanup: Over time, you'll accumulate many backup versions. Decide how far back you need to keep backups. For Git, this is just commit history (which is fine to keep indefinitely in most cases). If you're storing large JSON dumps in a storage bucket daily, implement a retention policy (e.g., keep daily for 30 days, weekly for 6 months, etc.). This is similar to typical backup rotation schemes​.
  • Align with Content Freeze or Deployment Windows: If you have a content freeze before a major release, that's a great time to run a full backup. Also, right after a big batch of changes (or a release launch) consider taking a snapshot. This ensures you have a known good state saved at critical points.

Having these backup mechanisms in place can greatly assist in several scenarios:

  • Accidental Deletion Recovery: A content editor might delete a composition or an entry by mistake. Uniform’s UI may not have a recycle bin for all item types, but with backups, you can retrieve the deleted content. For example, find the last JSON of that item in your backup repo and either re-import it via CLI or copy-paste the needed values to recreate manually. This can turn a potential crisis into a minor inconvenience.
  • Content Corruption or Mistakes: Perhaps a bulk edit or integration inadvertently altered many content items incorrectly. Rather than manually undoing changes, you could roll back the project to a prior state using the backups. Even if you don't fully restore, you can diff the backup JSON to pinpoint what changed and fix it.
  • Disaster Recovery: In an extreme case where data in the Uniform project is lost (due to a severe bug or an outage on Uniform’s side), having an external backup means you’re not solely reliant on Uniform’s infrastructure. You could redeploy your content to a new project or restore once the incident is resolved. This is a safety net that could save days of work rebuilding content from scratch​.
  • Audit and Change History: Your backup history can serve as an audit log for content changes. If you use Git, you can inspect the commit history to see when a particular piece of content changed and even who initiated it (if you log user info from webhooks or look at commit authorship). This can supplement Uniform’s own versioning features.
  • Testing and Development: Developers can use backups to set up local test data or seed a staging environment. For instance, a developer could pull the latest content from production (via backup files) and push it to a dev Uniform project to have realistic content for testing new features.
  • Content Migration: If at some point you needed to migrate content out of Uniform to another system (or vice versa), having the content in JSON format in a backup is extremely helpful. It's a structured record of all your content that could be transformed or imported elsewhere.

In all these cases, backups provide flexibility and insurance.

For completeness, here is a list of Uniform webhook event types relevant to content and configuration, along with what they represent. You can use this as a reference when deciding which events to subscribe to in your backup webhook:

  • Composition events:
    • composition.changed – Fires when a composition (page) is created or modified​.
    • composition.published – Fires when a composition is published (made live)​.
    • composition.deleted – Fires when a composition is deleted.
  • Composition (Release) events: (These occur in the context of a pre-launch release)
    • composition.release.changed – A composition in a release was changed or a composition was added to a release.
    • composition.release.published – A composition in a release was published (the release launched that composition).
    • composition.release.deleted – A composition in a release was deleted (removed from the release or the release’s copy).
    • composition.release.restored – A previously deleted composition in a release was restored.
  • Entry events:
    • entry.changed – Fires when an entry (structured content item) is created or updated.
    • entry.published – Fires when an entry is published.
    • entry.deleted – Fires when an entry is deleted.
  • Entry (Release) events: (analogous to composition release events, but for entries within a release)
  • entry.release.changed – An entry in a release was changed (or added)​.
    • entry.release.published – An entry in a release was published.
    • entry.release.deleted – An entry in a release was deleted from the release​.
    • entry.release.restored – A deleted entry in a release was restored​.
  • Manifest events:
    • manifest.published – Fires when a personalization manifest is published​. (This usually occurs after making changes to personalization, testing, or context definitions and publishing them, which generates an updated manifest that is deployed).
  • Project Map events:
    • projectmap.updated – Fires when a Project Map is created or updated (e.g., structural changes at the top level of the map)​.
    • projectmap.deleted – Fires when a Project Map is deleted.
    • projectmap.node.inserted – Fires when a new node is added to the Project Map (e.g., a new page added to navigation)​.
    • projectmap.node.updated – Fires when a node in the Project Map is updated (e.g., its name or path changed)​.
    • projectmap.node.deleted – Fires when a node is removed from the Project Map​.
  • Redirect events:
    • redirect.inserted – Fires when a new redirect rule is created​.
    • redirect.updated – Fires when an existing redirect rule is modified​.
    • redirect.deleted – Fires when a redirect is removed​.
  • Release events:
    • release.changed – Fires when a release definition (metadata like name, schedule) is changed​.
    • release.deleted – Fires when a release is deleted (along with its contents)​.
  • release.launch_started – Fires when a release begins the launching process​.
    • release.launched – Fires when a release has completed launching (all its content is published)​.
  • Workflow events:
    • workflow.transition – Fires when an item moves from one workflow stage to another​ (e.g., content moved from "Draft" to "Review"). The payload includes which item and what stages were involved.

When configuring backups, you would prioritize content-centric events (composition and entry events, plus project map, redirect) to capture the content and site structure changes. Release and workflow events are more for awareness/monitoring (you might log them to know when a release happened or content approval stage changed, but they don't carry actual content data in need of backup). Manifest events are important if you rely on Uniform’s personalization/testing – capturing the manifest (or underlying data via CLI) ensures you can restore those at all times.

Keep in mind that Uniform may add more event types as the platform evolves, so always refer to the latest documentation for any new events​. The above list is current as of this writing.

By using Uniform webhooks, you can achieve continuous, real-time backups of every content change, and by leveraging the Uniform CLI, you can take full snapshots and restore them when needed. Together, these approaches protect your "stack content" against accidental loss and empower you to recover quickly from issues with minimal downtime or data loss.

To summarize actionable steps:

  1. Set up Uniform webhooks for key events (changed/published/deleted for compositions, entries, etc.) and create a listener service that saves those changes externally.
  2. Use the Uniform CLI sync pull command to regularly export your project to JSON/YAML, and commit those backups to a Git repository (or other storage) for safekeeping and version history.
  3. Test the sync push restore process so you're confident you can re-import data if needed.
  4. Follow best practices in maintaining these backups (security, monitoring, and cleanup).

With these measures in place, you'll have a comprehensive backup and restore plan done your way. This not only gives peace of mind but also enhances your ability to manage content in a controlled, DevOps-friendly way – treating content as versioned data that can be moved and recovered just like code.

Last modified: April 28, 2025