Skip to content
npm

Embedding the builder ​

Renamed in 0.5.1

The component is <ngx-view-builder-designer> / NgxViewBuilderDesigner, matching the package it ships in. The former <ngx-view-builder-builder> selector and NgxViewBuilderBuilder class name still work as aliases, so existing templates keep rendering, but new code should use the names below.

Minimal setup ​

ts
import { Component } from '@angular/core';
import { BuilderModel, IStructure, NgxViewBuilderDesigner } from '@ngxviewbuilder/designer';

@Component({
  selector: 'app-builder-page',
  imports: [NgxViewBuilderDesigner],
  template: `
    <ngx-view-builder-designer
      [model]="builderModel"
      (structureChanged)="onStructureChanged($event)"
      (saveRequested)="onSave()"
    />
  `,
})
export class BuilderPageComponent {
  builderModel = new BuilderModel();

  ngOnInit(): void {
    const saved = localStorage.getItem('my-view');
    if (saved) {
      this.builderModel.setJson(saved); // takes a JSON string
    }
  }

  onStructureChanged(structure: IStructure): void {
    localStorage.setItem('my-view', JSON.stringify(structure)); // autosave
  }

  onSave(): void {
    // user clicked Save in the builder header
  }
}

BuilderModel wraps the structure: setJson(jsonString), getJson(): IStructure, plus setDataJson/getDataJson for preview data. An empty model starts with one blank page.

The view does not have to be there when the builder starts. When it comes from your backend, call setJson() once it arrives, or hand the builder a new BuilderModel; the canvas loads it and undo starts from it:

ts
ngOnInit(): void {
  this.http.get('/api/views/order-form', { responseType: 'text' })
    .subscribe((json) => this.builderModel.setJson(json));
}

Inputs ​

InputTypePurpose
modelBuilderModelThe structure being edited
languagestringBuilder UI + content language
theme'light' | 'dark'Color scheme
runtimeSettingsINgxViewBuilderBuilderSettingsThe big config object (below)
headerActionsINgxViewBuilderHeaderAction[]Extra header buttons
hideSaveActionbooleanHide the built-in Save
hideHeaderTabsbooleanChrome-less embedding
activeTabtab codePreselect a tab
uiDictionariesUiDictionariesBuilder UI translations
contentTranslationsRecord<lang, Record<key,string>>Content translations
cssVariablesRecord<string,string>Token overrides
viewportSettings{ mobile?, tablet?, desktop? }Preview breakpoint widths
externalConfig / externalConfigUrlconfig object / URLLoad host config as an object or JSON file

runtimeSettings highlights ​

ts
readonly builderSettings: INgxViewBuilderBuilderSettings = {
  theme: 'light',
  language: 'en',
  builderPageDisplayMode: 'single',        // canvas shows one page at a time
  dataSources: { enableWebsocket: true },
  defaultDataSources: [...],               // sources every view gets
  runtimeVariableContext: { userRole: 'admin' },
  propertyHints: { name: 'Unique data key' },  // extra hint texts in the sidebar
  mcp: { url: 'wss://mcp.example.com/bridge' },  // let an AI client drive the builder
  licenseKey: 'NVB-...',
};

mcp is optional. With it, the builder connects to an MCP server while it is on screen and shows a session key under Settings → AI access (MCP), which a person gives to their AI client to let it edit the view. See AI command API.

Outputs ​

OutputFires when
structureChangedany edit changes the structure (autosave hook)
saveRequestedSave is clicked
valueChangeda preview value changes
tabChanged / languageChangednavigation events
templateSaved / templateDeleted / templatesLoadedtemplate library persistence (host-side storage)
sidebarGroupSaved / sidebarGroupDeleted / sidebarGroupsLoadedelement-library persistence
headerActionRequestedone of your headerActions was clicked

Custom header actions ​

ts
readonly headerActions: INgxViewBuilderHeaderAction[] = [
  { id: 'save', label: 'Save', icon: 'save', tone: 'primary',
    onClick: () => this.saveToBackend() },
  { id: 'publish', label: 'Publish', onClick: () => this.publish() },
];

Persisting templates and library items ​

When creators save templates or sidebar library groups, the builder emits events instead of assuming storage. Listen, persist wherever you like, and feed items back on startup:

ts
ngAfterViewInit(): void {
  queueMicrotask(() => {
    this.api.loadTemplates(this.templatesFromBackend);
    this.api.loadSidebarGroups(this.groupsFromBackend);
  });
}

(api is NgxViewBuilderApiService.)