Backstage CMS

2022 - 2024

The Backstage CMS project was a ground-up rebuild of VICE's headless content management system, migrating the frontend from Vue.js to Next.js while also migrating it's backend integration from a legacy REST API to a new GraphQL API.

I was the engineering manager, lead and project manager. I also hired two engineers to dedicate to this project.

Backstage CMS edit page example

Technical Highlights

Features

  • Publish and schedule a variety of content types
  • Curate content for landing pages
  • User roles and permissions
  • Auto-save
  • Real-time view of who is working on what
  • Safety mechanisms to prevent losing unsaved work or overwriting others

Auto-save

Backstage CMS auto-saves the user's work. Every time a user pauses for more than a couple seconds, their work will automatically save to the server.

View the video below to observe a user editing an article. Notice how the buttons in the upper-right disable briefly while auto-save is running. The user is also never interrupted while saving. At the end of the video, the article is finally scheduled to go live.

The Challenge

Early in the project, React Final Form was chosen to handle our form state management, primarily for it's Redux-inspired performance tuning capability. While React Final Form provides some ways to implement auto-save (i.e. keepDirtyOnReinitialize), it doesn't handle re-hydrating the form with data from the server while also not interrupting the user.

VMForm was created to address this; a wrapper around React Final Form's Form component and implemented a custom onSave prop that allows the form to re-hydrate the form after submission completes. VMForm also keeps track of any fields that are changed (or "dirtied") while the form submission is in progress so that it knows which fields to not overwrite. VMForm is also designed to be a drop-in replacement for Form as all capability and hooks native to React Final Form still work.

Data Flow / Lifecycle

To further illustrate the impact this auto-save design has on how data flows through the app, observe the following sequence diagrams that depict the data flow design proposed by React Final Form vs VMForm.

React Final Form (Before)

Backstage CMS data flow before

VMForm (After)

Backstage CMS data flow after

Strict Types For Form Data

Any data-heavy application should use strict typing and a CMS is a perfect example of this. While the types directly conforming to a GraphQL API Schema can be automatically generated via tools like CodeGen, the data returned from an API are often not in the most convenient structure for UI components, form validation, etc.

As Backstage CMS is a Typescript application, patterns were implemented for the team to follow in order to restructure this data for ease within the UI while preventing hardcoded strings from being sprinkled throughout the codebase.

Dirty Warning Modal

Backstage CMS provides mechanisms to prevent users from losing their work. One in particular is the "Dirty Warning Modal".

The tricky part was cancelling native browser navigation and Next.js client-side rendering while keeping the browser and the Next.js router in sync. The different types of navigation also means that two types of modals need to be used to prompt the user depending on how they leave the page.

Backstage CMS custom dirty warning modalBackstage CMS native dirty warning modal

As long as DirtyWarningModal exists as a child of a React Final Form Form component, the user will always be prompted if they attempt to leave the page while the form is dirty.