Web Development Blog — Coding, SEO, Domains & CMS Insights

Why You Can’t Prefill Complex HubSpot Modules

Written by Niko Yankovsky | January 25, 2026

If you’ve ever tried to ship a complex HubSpot module — a quiz, calculator, or configurator — you’ve probably asked the same question: why does everything start empty, even when defaults are defined? This article explains why that happens, what HubSpot actually allows, and which patterns work in production.

fields.json Expectations vs Reality

At first glance, HubSpot modules look declarative. You define structure and defaults in fields.json, and it feels natural to expect the module to arrive with meaningful demo content.

In theory, this would mean:

  • the module is added to a page;
  • repeaters are already populated;
  • demo content is ready to use;
  • the editor tweaks instead of building from scratch.

Unfortunately, this expectation does not match how HubSpot modules actually work.

Defaults Are Not Seed Data

The most important distinction to understand is this:

Defaults in fields.json are fallback values, not content initialization.

However, in practice, HubSpot’s editor does not apply defaults eagerly. Some default values — especially inside repeaters — may only appear after the editor re-normalizes data in response to user interaction. This behavior is undocumented and inconsistent, and should not be relied on.

They exist to:

  • define field structure;
  • provide UI hints;
  • prevent null rendering.

They do not:

  • create repeater items;
  • populate nested fields;
  • act as demo content.

This difference is subtle, poorly documented, and responsible for most confusion.

Example: Default on a Simple Field

This may appear prefilled in some cases — but this behavior does not extend to repeaters.

Where It Breaks First: Repeaters

Simple fields behave as expected. A text field with a default value will render correctly. Repeaters behave differently.

If a field group is marked as repeatable, HubSpot will never auto-create items for it — even if every child field has a default value.

The result is always the same:

  • the repeater exists;
  • item count is zero;
  • the editor UI is empty.

This is intentional and consistent behavior.

Example: Repeatable Group With Defaults That Will Not Appear

Despite the default value, no question item will be created.

Nested Repeaters: No Escape Hatch

Most real-world modules are not flat. In quizzes and assessments, repeaters are often nested multiple levels deep.

For example:

  • Questions
  • Answers
  • Scoring rules

HubSpot provides no supported mechanism to prefill this hierarchy:

  • not via Design Manager;
  • not via the browser editor;
  • not via CLI;
  • not via undocumented flags.

Once this limitation is understood, many confusing behaviors suddenly make sense.

Example: Nested Repeatable Structure

No part of this structure will be auto-populated.

The CLI Preset Illusion: A Real-World Case

While working on a production quiz module with deeply nested repeaters (questions → answers → scoring rules), I attempted to prepare a full demo preset via the HubSpot CLI by defining complete default values in fields.json.

When the module was added to a page, the result looked broken:

  • some helper texts were missing;
  • boolean toggles appeared disabled;
  • repeater items shared duplicated values;
  • nested answer data appeared empty.

At first glance, this looked like partial failure of defaults — or even a CLI bug.

However, something unexpected happened.

After adding or removing any repeater item in the editor UI, all previously broken fields suddenly normalized:

  • missing defaults appeared;
  • duplicated values corrected themselves;
  • nested repeaters populated correctly.

This behavior creates the illusion that repeaters can be fully prefilled via CLI — but that conclusion is misleading.

What Actually Happened: Lazy Editor Normalization

HubSpot does not eagerly apply defaults when a module is first added to a page. Instead, the editor performs partial initialization and defers full normalization until the user mutates repeater data.

When a repeater item is added or removed, the editor re-processes the entire structure:

  • missing values are filled from defaults;
  • undefined fields are normalized;
  • nested structures are reconciled.

This process is internal, undocumented, and not guaranteed to run on initial render.

The CLI did not “seed” content. It merely defined a schema that the editor later reconciled during user interaction.

Can This Be Done in the Browser?

No.

The Design Manager UI allows you to define module structure, but it does not provide any way to inject instance data when a module is added to a page.

Every module instance starts empty by design.

What About the HubSpot CLI?

This is a common assumption and an understandable one.

The HubSpot CLI operates on module source files, not on page instances. Fetching or pushing a module only updates its definition.

It does not:

  • prefill editor data;
  • modify existing page instances;
  • seed repeater content.

Example: CLI Commands That Do Not Seed Content

These commands sync schema — nothing more.

In some cases, deeply defined defaults may appear to populate after editor interaction. This is a side effect of internal editor normalization — not a supported content seeding mechanism.

Why HubSpot Works This Way

This limitation is not a bug — it is a deliberate architectural decision.

HubSpot modules are designed to be:

  • safe for non-technical editors;
  • predictable across updates;
  • free from silent content mutations.

Allowing modules to auto-seed complex data would introduce serious risks:

  • content being overwritten on updates;
  • unexpected editor-side mutations;
  • unstable Marketplace behavior.

HubSpot chose content ownership over automation.

The Demo Content Problem

This design choice creates a real challenge for complex modules:

  • quizzes;
  • calculators;
  • multi-step assessments;
  • interactive flows.

Without demo content, first-time UX suffers and support questions increase.

Why This Should Not Be Used as a Preset Strategy

Relying on editor-side normalization for demo content is risky:

  • users may save the page before normalization occurs;
  • behavior varies between modules and updates;
  • Marketplace reviewers do not treat this as supported functionality.

If demo content matters, it must be controlled at runtime — not inferred from editor side effects.

Patterns That Actually Work

Runtime Seeding via HUBL (Server-First)

The most reliable approach is to resolve demo versus real data at the template level, before JavaScript execution.

Instead of trying to prefill or mutate iterable fields at runtime, the module decides which dataset to expose based on a clear condition.

This allows:

  • fully nested and predictable data structures;
  • no mutation of editor-configured fields;
  • clear separation between authoring logic (HUBL) and runtime behavior (JavaScript).

This is the approach used in the Persona Scoring Quiz module.

Example: Runtime Seeding Pattern

Explicit Demo Mode Toggle via HUBL

For complex modules, heuristic checks are often not enough. A more robust solution is to expose an explicit Demo Mode toggle.

This makes behavior deterministic and fully controlled by the editor:

  • demo content on;
  • editor content ignored.

Example: Demo Mode Toggle via HUBL

What Will Never Work

  • defaults in repeaters;
  • nested default propagation;
  • CLI-based content injection;
  • hidden or undocumented flags.

If someone claims otherwise, they are confusing schema with instance data.

Final Takeaway

If you are building advanced HubSpot modules:

  • treat fields.json as schema only;
  • move demo logic to runtime;
  • document the behavior clearly;
  • respect content ownership;
  • editor normalization effects exist, but must not be treated as API or preset functionality.

HubSpot modules are powerful — once their boundaries are understood.