Renaming a Module Field on 60 Live Pages
A SaaS company has a custom theme with a hero-banner module used on 60 marketing pages and referenced by 12 page templates via {% module "hero" path="./modules/hero-banner.module" %}. The module's fields are headline (text), image (image), and cta_link (link). The brand team wants a new hero with an optional eyebrow, a second CTA, and a background video. A junior developer proposes renaming headline to title and cta_link to primary_cta so the field names match the new design system. They plan to edit fields.json and module.html, then push with the CLI. Content editors have already set hero copy and images on all 60 pages. The team cannot afford to re-enter content page by page.
1. Evaluate the proposal to rename headline and cta_link. What breaks, and what is the safe alternative?
Read the worked answer
Renaming a field's name changes the key HubSpot uses to store the value for every existing module instance. The 60 pages still hold values under headline and cta_link; after the rename, the editor looks for title and primary_cta, finds nothing, and shows defaults or blanks. The rendered template also breaks where it references module.headline. Cloning the module or editing fields.json does not migrate stored instance data.
The safe approach is additive. Keep headline, image, and cta_link exactly as they are. Add eyebrow, secondary_cta, and background_video as new optional fields with sensible defaults. Update module.html to render the new elements conditionally, for example {% if module.eyebrow %}. If the old field label is confusing, change the label in fields.json, not the name. If semantic cleanup is truly needed, introduce new fields, migrate content deliberately, and only then retire old fields after confirming no page or template references them. Renaming for cosmetic consistency is not worth a 60-page content migration.
2. Describe a rollout plan that updates the design on all 60 pages without content re-entry, including templates and page-level module instances.
Read the worked answer
Treat this as an in-place upgrade, not a module replacement. Add the new fields to the existing module's fields.json; do not change the module's path or filename, because 12 templates reference it by path and page instances are tied to that module. Keep the current markup as the base and add conditional blocks for eyebrow, second CTA, and video. Give the new fields defaults that preserve the current look when empty, so pages that never set them do not change.
Deploy to a sandbox first. Open several of the 60 pages in the page editor, confirm the old headline, image, and CTA still populate, then set the new fields on one test page. Check the template-referenced instances separately from page-level instances. If some pages need a fundamentally different hero, resist swapping all 60 to a new module; instead add a layout choice field with a default of the current layout. That keeps stored content intact and lets editors opt in page by page. After production deploy, spot-check pages with and without the new fields.
3. How would you verify backward compatibility before deploying to production?
Read the worked answer
Before production, fetch the live theme into a branch so the test starts from real production files, not an outdated repo copy. Run the theme against a sandbox portal and open a representative sample: a page with all old fields set, a page with only headline, a page using the module through a template, and a page where the module was added directly in the editor. In each, confirm the page editor loads without field errors and that old values appear in the correct inputs. Inspect the rendered HTML for the fallback path when eyebrow or secondary_cta is empty. Check that no template still references a renamed field and that no duplicate module path was introduced. Also test a fresh module instance: new fields should show defaults, and the page should not look broken before an editor touches it. If any page shows blank old content, stop; that is a storage-key regression, not a styling issue.