---
url: 'https://dxpr.com/hc/documentation/learn-dxpr-builder/development/submodules'
title: 'Submodules | 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: 'The three submodules and what each one provides'
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: Submodules
      description: 'The three submodules and what each one provides'
      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/submodules'
      articleSection: 'Architecture and APIs'
    -
      '@type': WebPage
      '@id': 'https://dxpr.com/hc/documentation/learn-dxpr-builder/development/submodules'
      description: 'The three submodules and what each one provides'
      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) # Submodules.

The three submodules and what each one provides

 Learn DXPR BuilderExtendArchitecture and APIs

   ## In this guide

 Related guides

- [Content types](/hc/documentation/learn-dxpr-builder/integrations/content-types)
- [Media Library](/hc/documentation/learn-dxpr-builder/integrations/media-library)

The `modules/` directory holds three submodules. Two are small configuration packages: a content type and a block type wired to the builder. The third is the legacy Entity Browser media picker that predates Media Library support. This page documents what each one installs, what it depends on, and how to enable or retire it.

| Module | Machine name | Provides | Status |
|---|---|---|---|
| DXPR Builder Drag and Drop Page | `dxpr_builder_page` | `drag_and_drop_page` content type | Supported |
| DXPR Builder Block Type | `dxpr_builder_block` | `drag_and_drop_block` block type | Supported |
| DXPR Builder Media | `dxpr_builder_media` | Entity Browser media picker | Legacy; hidden from the Extend page |

None of them is required. The builder works on any text field whose view display uses the **DXPR Builder** formatter (`dxpr_builder_text`); see [Installing on existing content types](/hc/documentation/learn-dxpr-builder/getting-started/installing-on-existing-content-types).

## DXPR Builder Drag and Drop Page

`modules/dxpr_builder_page` installs the **Drag and Drop Page**content type (`node.type.drag_and_drop_page`) from `config/optional/`:

- The `body` field, with the default view display using the `dxpr_builder_text` formatter and the form display grouped with Field Group.
- Three DXPR Theme fields: `field_dth_hide_regions`, `field_dth_main_content_width` and `field_dth_page_layout`. They install only when their field storages exist, which the DXPR Theme Helper module provides.

Dependencies from `dxpr_builder_page.info.yml`: `field_group`, `text`, `node` and `dxpr_builder`. `hook_install()` creates the `body` field storage when it does not exist. When the optional config cannot install, as on the Minimal profile, it installs the type, body field and displays itself, without the `menu_ui` and `path` parts. `dxpr_builder_page_update_8001()` marks the installed config as enforced by the module.

`src/DXPRBuilderPageUninstallValidator.php` (registered in `dxpr_builder_page.services.yml`) blocks uninstalling while any `drag_and_drop_page` node exists. Delete or change the type of those nodes first.

1. Enable the module:

    ```bash
    drush en dxpr_builder_page -y

    ```
2. Create a page at `/node/add/drag_and_drop_page`. The builder starts on the body field when the page is viewed by an editor.

If enabling fails with "unmet dependencies", enable Field Group and check that a `body` field storage exists; see [Problems after updating](/hc/documentation/learn-dxpr-builder/troubleshooting/after-updating).

## DXPR Builder Block Type

`modules/dxpr_builder_block` installs the **Drag and Drop Block**block type (`block_content.type.drag_and_drop_block`) from `config/optional/`, with a `body` field, the `dxpr_builder_text`formatter on the default view display, and the form display. The type has **Create new revision** turned on, and `dxpr_builder_block_update_8002()` turns it on for older installs, so every builder save on a block creates a revision (see [Content staging](/hc/documentation/learn-dxpr-builder/advanced/content-staging)).

Dependencies: `text`, `node` and `dxpr_builder`.

1. Enable the module:

    ```bash
    drush en dxpr_builder_block -y

    ```
2. Create a block at `/block/add/drag_and_drop_block`.
3. Place it in a region. Editors edit it in place on any page where it appears.

`dxpr_builder_entity_type_alter()` swaps in the module's own `Drupal\dxpr_builder\Entity\BlockContent` class, as it does for `Node`. The class saves an empty string into empty builder fields, so the editor always has something to attach to. A block type you create yourself therefore works the same way once its view display uses the DXPR Builder formatter.

## DXPR Builder Media

`modules/dxpr_builder_media` is the Entity Browser based image picker that the module used before core Media Library support. It is marked `hidden: true` in its `.info.yml`, so it does not appear at **Extend**; you can still enable it with Drush. It installs:

- `entity_browser.browser.dxpr_builder_media_modal`: a modal browser labelled **DXPR Builder Image Browser** with two widgets, a **Media Library** tab backed by the `dxpr_builder_media` View and an **Upload new image** tab that creates an `image` media entity through Inline Entity Form.
- `views.view.dxpr_builder_media`: the media grid for the first widget.
- `image.style.dxpr_builder_media_thumbnail`: a 300 by 300 pixel scale-and-crop style for the grid.
- Libraries `view`, `claro_style` and `gin_style`(`dxpr_builder_media.libraries.yml`). The module attaches the Gin stylesheet to the View when the active theme is Gin or based on it, and the Claro stylesheet otherwise.

Dependencies: `inline_entity_form`, `entity_browser`, `entity_browser_entity_form`, `media`, `media_library` and `views`. On install the module sets `media_browser` in `dxpr_builder.settings` to `dxpr_builder_media_modal`; on uninstall it sets it to an empty string (**Basic file upload**) and deletes the image style.

The recommended browser is core Media Library, which needs no submodule:

1. Uninstall the legacy module if it is enabled:

    ```bash
    drush pm:uninstall dxpr_builder_media -y

    ```
2. Go to **DXPR Studio &gt; DXPR Builder &gt; General Settings**(`/admin/dxpr_studio/dxpr_builder/settings`) and open **Media**.
3. Set **Browser type** to **Media Library** and click **Save settings**. The uninstall has reset it to **Basic file upload**.

Keep the submodule only on a site that depends on an Entity Browser that returns file IDs; see [Images do not upload or disappear](/hc/documentation/learn-dxpr-builder/troubleshooting/images-and-media)for the errors a mismatched browser produces. The module carries the repository's only PHPUnit test, `tests/src/FunctionalJavascript/MediaEntityBrowserTest.php`; see [Testing](/hc/documentation/learn-dxpr-builder/development/testing).

## Enabling several at once

```bash
drush en dxpr_builder_page dxpr_builder_block -y

```

Each submodule is independent of the others.

## What's next?

- [Content types](/hc/documentation/learn-dxpr-builder/integrations/content-types) for using the builder on your own content types.
- [Media Library integration](/hc/documentation/learn-dxpr-builder/integrations/media-library) for the recommended image picker.