---
url: 'https://dxpr.com/hc/documentation/learn-dxpr-builder/development/architecture'
title: 'Architecture | DXPR'
author:
  name: docs-sync
  url: 'https://dxpr.com/users/docs-sync'
date: '2026-10-23T14:31:17+00:00'
copyright: 'Copyright DXPR. All rights reserved.'
type: article
summary: 'How the field, the editor and the front-end script work together'
tags:
  - 'Architecture and APIs'
image: 'https://dxpr.com/themes/custom/dxpr_com/images/dxpr-share-card.jpg'
published: true
og:
  site_name: DXPR
  updated_time: '2026-10-23T14:31:17+0000'
  'image:alt': 'DXPR, powered by Drupal: AI-powered Drupal for marketers.'
schema:
  '@context': 'https://schema.org'
  '@graph':
    -
      mainEntity: {  }
    -
      '@type': TechArticle
      headline: Architecture
      description: 'How the field, the editor and the front-end script work together'
      image:
        '@type': ImageObject
        url: 'https://dxpr.com/themes/custom/dxpr_com/images/dxpr-share-card.jpg'
        width: '1200'
        height: '630'
      datePublished: '2026-10-23T14:31:17+0000'
      dateModified: '2026-10-23T14:31:17+0000'
      author:
        '@type': Organization
        '@id': 'https://dxpr.com/#organization'
        name: DXPR
        url: 'https://dxpr.com/'
        logo:
          '@type': ImageObject
          url: 'https://dxpr.com/themes/custom/dxpr_com/dxpr-logo-dark.svg'
          width: '1348'
          height: '501'
      publisher:
        '@type': Organization
        '@id': 'https://dxpr.com/#organization'
        name: DXPR
        url: 'https://dxpr.com/'
        logo:
          '@type': ImageObject
          url: 'https://dxpr.com/themes/custom/dxpr_com/dxpr-logo-dark.svg'
          width: '1348'
          height: '501'
      mainEntityOfPage: 'https://dxpr.com/hc/documentation/learn-dxpr-builder/development/architecture'
      articleSection: 'Architecture and APIs'
    -
      '@type': WebPage
      '@id': 'https://dxpr.com/hc/documentation/learn-dxpr-builder/development/architecture'
      description: 'How the field, the editor and the front-end script work together'
      breadcrumb:
        '@type': BreadcrumbList
        itemListElement:
          -
            '@type': ListItem
            position: 1
            name: Home
            item: 'https://dxpr.com/'
      publisher:
        '@type': Organization
        '@id': 'https://dxpr.com/#organization'
        name: DXPR
      inLanguage: en
---
[Help Center](/hc)/[Documentation](/hc/documentation) /[Learn DXPR Builder](/hc/documentation/learn-dxpr-builder) /[Extend](/hc/documentation/learn-dxpr-builder/extend) /[Architecture and APIs](/hc/documentation/learn-dxpr-builder/extend/architecture) # Architecture.

How the field, the editor and the front-end script work together

 Learn DXPR BuilderExtendArchitecture and APIs

   ## In this guide

DXPR Builder has three parts: a field formatter in PHP, an editor that runs in the browser, and a set of routes that the editor calls to save and fetch data. This page explains how they fit together.

## Field formatter

Content is HTML stored in an ordinary Drupal text field (`text`, `text_long` or `text_with_summary`). A field becomes editable when its view display uses the **DXPR Builder** formatter (`dxpr_builder_text`, in `src/Plugin/Field/FieldFormatter/DxprBuilderFormatter.php`).

The formatter loads the editor only when all of these hold:

- the viewer is billable: user 1, or an active account with `edit with dxpr builder` that is not excluded from DXPR Builder editing;
- the viewer may update the entity;
- the account has an email address;
- the licence's user and content limits are not exceeded;
- the site is not on the licence server's blocklist, and the page is not a revisions page.

Everyone else gets the processed HTML: path tokens expanded, Drupal blocks and views rendered into their placeholders, the `data-az*`editor attributes removed, and the libraries the content needs attached. Output for logged-in users is not cached (`max-age` 0), because it carries per-user settings.

## Editor

The editor is a set of JavaScript files loaded as the `dxpr_builder/editor.builder` library. They come from DXPR's CDN, or from the module's own `dxpr_builder/` folder when it holds a local build; the **Asset source** setting on General Settings appears only then. The editor parses the field's HTML into a tree of element objects and writes it back to HTML when it saves.

Element types come from two places in `dxpr_builder/build/`:

| Folder | Element types |
|---|---|
| `dxpr-builder/core-elements/` | Container, Section, Row, Column, Tabs and their tab, toggle and slide panels |
| `dxpr-elements/elements/` | Content elements and the Collapsibles, Carousel and Positioned Layers layout elements |

Each element keeps its settings in its own HTML: `data-azat-*`attributes, classes and inline styles. The stored HTML is the only record of the layout; there is no separate layout storage. [Custom elements](/hc/documentation/learn-dxpr-builder/development/custom-elements) shows the format.

### Parsing existing HTML

Markup without builder attributes is mapped to elements when the editor loads it. Bootstrap containers, rows and columns become sections, rows and columns. Recognised components become their elements, for example buttons, alerts, cards, blockquotes, images, icons, progress bars, tabs and collapsibles. Text, tables and other inline markup become Text elements, and an `<iframe>` becomes an HTML element. Loose `<script>` and `<style>` tags and comments are dropped. The rules are in `dxpr-builder/base-element/parse-html.js`.

## Routes the editor calls

The editor saves through `/dxpr_builder/ajax`, uploads files through `/dxpr_builder/ajax/file_upload` and reaches AI through `/dxpr_builder/ajax/ai/*`. Most routes check the billable user access check and a CSRF token; the full list with access requirements is in the [API reference](/hc/documentation/learn-dxpr-builder/development/api#editor-routes).

## Configuration entities

| Entity type | Config prefix | Holds |
|---|---|---|
| `dxpr_builder_page_template` | `dxpr_builder.page_template` | Full-page layouts |
| `dxpr_builder_user_template` | `dxpr_builder.user_template` | Sections editors saved for reuse |
| `dxpr_builder_profile` | `dxpr_builder.dxpr_builder_profile` | Per-role limits on elements, blocks, views, templates, icon sets and text editor buttons |

## Licence check

The product key is a JWT. `DxprBuilderLicenseService` sends it to the DXPR licence server, which returns the licence status and its user and content limits; the result is cached. Without a product key the free tier applies: one user and 100 content items. The service also keeps the server's list of this site's editors in sync.