---
title: 'Administration Modules: Structure and Extension | Shopware Community Hub'
description: >-
  Learn how to structure administration modules and extend existing
  administration features by using clear entry points before reaching for
  heavier overrides.
canonical_url: >-
  https://hub.shopware.com/learn/unit/administration-modules-structure-and-extension
---

# Administration Modules: Structure and Extension

<LearningObjectives>

- Understand why larger administration modules need a clear folder structure with pages, views, components, snippets, and ACL rules.
- Learn how pages, views, and components work together inside an administration module.
- Create a maintainable folder structure for larger administration features.
- Understand why a module itself is not extended directly, but its parts can be extended or overridden.
- Learn how to choose suitable extension points before using heavier overrides.

</LearningObjectives>

# Administration Modules: Structure and Extension

In the previous course, you learned how to register a basic Shopware administration module. Before we go deeper, let's start with a quick checkpoint:

<ArticleMultipleQuestionnaire>
  <ArticleQuestionnaire>
    <ArticleQuestionnaireQuestion>What is correct about modules in the Shopware Administration?</ArticleQuestionnaireQuestion>
    <ArticleQuestionnaireAnswer correct>You register a module with 'Shopware.Module.register()'</ArticleQuestionnaireAnswer>
    <ArticleQuestionnaireAnswer>A module only contains '.js' files</ArticleQuestionnaireAnswer>
    <ArticleQuestionnaireAnswer>A module is the same as a component</ArticleQuestionnaireAnswer>
    <ArticleQuestionnaireAnswer correct>Modules typically define routes that map to pages</ArticleQuestionnaireAnswer>
  </ArticleQuestionnaire>
</ArticleMultipleQuestionnaire>

Creating a basic administration module with `bin/console plugin:create` is a great first step, but real-world modules quickly grow beyond the generated skeleton. A single module might contain multiple pages, views, snippets, ACL rules, and dozens of components. **Means:** for larger features, you must reorganize your modules to keep it maintainable, readable, and easy to extend.

## Recommended Folder Structure

Large administration extensions quickly become complex. A well-structured module is easier to maintain, extend, and read.

A typical setup inside your plugin could look like this:

The example module names below use `swag-*` because they follow common Shopware demo naming. In your own projects, use a unique company, plugin, or project prefix to avoid collisions with core, commercial extensions, or other plugins.

```text
└── [shop_root]
     └── custom
         └── plugins
             └── [your_plugin]
                  └── src
                      └── Resources
                          └── app
                              └── administration
                                  └── src
                                      ├── module
                                      │   ├── swag-black-friday
                                      │   │   ├── acl
                                      │   │   │   └── index.js // Define privileges for the module
                                      │   │   ├── component
                                      │   │   │    │── my-component-one
                                      │   │   │    │   │── my-component-one.html.twig
                                      │   │   │    │   │── my-component-one.scss
                                      │   │   │    │   └── index.js
                                      │   │   │    │── my-component-two
                                      │   │   │    │   │── my-component-two.html.twig
                                      │   │   │    │   │── my-component-two.scss
                                      │   │   │    │   └── index.js
                                      │   │   ├── page
                                      │   │   │    │── swag-black-friday-create
                                      │   │   │    │   │── swag-black-friday-create.html.twig
                                      │   │   │    │   │── swag-black-friday-create.scss
                                      │   │   │    │   └── index.js
                                      │   │   │    │── swag-black-friday-detail
                                      │   │   │    │   │── swag-black-friday-detail.html.twig
                                      │   │   │    │   │── swag-black-friday-detail.scss
                                      │   │   │    │   └── index.js
                                      │   │   │    └── swag-black-friday-list
                                      │   │   │        │── swag-black-friday-list.html.twig
                                      │   │   │        │── swag-black-friday-list.scss
                                      │   │   │        └── index.js
                                      │   │   ├── snippet
                                      │   │   │    │── de-DE.json
                                      │   │   │    │── en-GB.json
                                      │   │   │    │── fr-FR.json
                                      │   │   │    │── it-IT.json
                                      │   │   │    └── ....json // More language files
                                      │   │   ├── view
                                      │   │   │    │── swag-black-friday-detail-base
                                      │   │   │    │   │── swag-black-friday-detail-base.html.twig
                                      │   │   │    │   │── swag-black-friday-detail-base.scss
                                      │   │   │    │   └── index.js
                                      │   │   │    │── swag-black-friday-detail-variants
                                      │   │   │    │   │── swag-black-friday-detail-variants.html.twig
                                      │   │   │    │   │── swag-black-friday-detail-variants.scss
                                      │   │   │    │   └── index.js
                                      │   │   │    └── swag-black-friday-detail-context-prices
                                      │   │   │        │── swag-black-friday-detail-context-prices.html.twig
                                      │   │   │        │── swag-black-friday-detail-context-prices.scss
                                      │   │   │        └── index.js
                                      │   │   └── index.js // Modules "main" file
                                      │   ├── swag-christmas
                                      │   │   ├── acl
                                      │   │   │   └── index.js
                                      │   │   ├── component
                                      │   │   │    │── my-component-one
                                      │   │   │    │   │── my-component-one.html.twig
                                      │   │   │    │   │── my-component-one.scss
                                      │   │   │    │   └── index.js
                                      │   │   ├── page
                                      │   │   │    │── swag-christmas-create
                                      │   │   │    │   │── swag-christmas-create.html.twig
                                      │   │   │    │   │── swag-christmas-create.scss
                                      │   │   │    │   └── index.js
                                      │   │   │    │── swag-christmas-detail
                                      │   │   │    │   │── swag-christmas-detail.html.twig
                                      │   │   │    │   │── swag-christmas-detail.scss
                                      │   │   │    │   └── index.js
                                      │   │   │    └── swag-christmas-list
                                      │   │   │        │── swag-christmas-list.html.twig
                                      │   │   │        │── swag-christmas-list.scss
                                      │   │   │        └── index.js
                                      │   │   ├── snippet
                                      │   │   │    │── de-DE.json
                                      │   │   │    │── en-GB.json
                                      │   │   │    └── ....json
                                      │   │   ├── view
                                      │   │   │    │── swag-christmas-base
                                      │   │   │    │   │── swag-christmas-base.html.twig
                                      │   │   │    │   │── swag-christmas-base.scss
                                      │   │   │    │   └── index.js
                                      │   │   │    │── swag-christmas-variants
                                      │   │   │    │   │── swag-christmas-variants.html.twig
                                      │   │   │    │   │── swag-christmas-variants.scss
                                      │   │   │    │   └── index.js
                                      │   │   │    └── swag-christmas-context-prices
                                      │   │   │        │── swag-christmas-context-prices.html.twig
                                      │   │   │        │── swag-christmas-context-prices.scss
                                      │   │   │        └── index.js
                                      │   │   └── index.js
                                      │   └── // More modules
                                      └── main.js // Main file to import all modules
```

At first glance, this can look like a lot of folders. Let's break it down:

### Module-Level Folder Structure

Each entry under `module/` represents **one administration module**:

- `swag-black-friday`
- `swag-christmas`
- And more, if needed.

Inside each module, folders have a clear purpose:

| Folder      | Purpose                                                                                               |
|-------------|-------------------------------------------------------------------------------------------------------|
| `acl`       | Defines privileges (ACL) for this module, e.g., which roles may read, edit or delete data.            |
| `component` | Contains reusable UI building blocks (`.html.twig`, `.scss`, `.js`) used **only within** this module. |
| `page`      | Contains the **top-level pages** of module (list, detail, create) that show up as routes.             |
| `snippet`   | Contains the translation files used by this module.                                                   |
| `view`      | Contains the **sub-views** inside of a page.                                                          |

Each module contains its own `index.js` file, which is the **main entry point** for that module. It registers the module with `Shopware.Module.register()`, define routes, connect pages

<Callout title="Page vs. View – What's the difference?" type="info">

- A **page** is the entry point for a route (e.g., `/sw/product/detail/:id`).
- A **view** is a smaller section inside a page (e.g., 'Base', 'Variants', 'Context Prices' tabs).

Pages define routes

</Callout>

The top-level `administration/src/index.js` then imports each module's `index.js` file, so Shopware can register them all. This way, each module becomes a **self-contained feature** with its own pages and views, components, snippets and ACL rules.

This approach is common for larger projects, where each module is a self-contained feature – Shopware core-administration follows this pattern as well.

Feel free to dive deeper into modules defined in [Shopware](https://github.com/shopware/shopware/tree/trunk/src/Administration/Resources/app/administration/src/module) to get a better understanding.

### Page vs. View vs. Component

When building larger administration modules, it is essential to understand how pages, views, and components relate to each other. Each layer serves a different purpose inside the module structure.

**Page:**

A page is the entry point of a route. It represents a full page in the administration, e.g., `/sw/product/detail/:id`. Examples: `sw-product-list`, `sw-product-detail`, `sw-product-detail`. Pages define **routes** and contain the overall layout for that route.

**View:**

A view is a smaller section **inside** a page, often used to split complex detail pages into logical areas. Views do **not** have their own routes – they live within a page.

While views can contain conditional logic (e.g., only show a section when data exists), their primary purpose is page structure.

**Component:**

Components are the smallest UI building blocks. They can be used inside pages and views and usually represent reusable UI elements.

Components do **not** define routes or page structure – they provide UI and logic that can be reused.

**In summary:**

- Use a **page** if you need a new custom page.
- Use a **View** if you need a smaller section or structure inside a page.
- Use Components if you need reusable UI parts used inside views or pages.

This layering is heavily used in the Shopware core-administration and is essential for building scalable modules.

## Extend a Shopware Module

Before you start, here is a quick checkpoint:

<ArticleMultipleQuestionnaire>
  <ArticleQuestionnaire>
    <ArticleQuestionnaireQuestion>Can an existing administration module be extended directly`Shopware.Module.extend()`?</ArticleQuestionnaireQuestion>
    <ArticleQuestionnaireAnswer>Yes, `Shopware.Module.extend()` is used to extend an existing module</ArticleQuestionnaireAnswer>
    <ArticleQuestionnaireAnswer correct>No, but it is possible to extend its parts (pages, views, components)</ArticleQuestionnaireAnswer>
  </ArticleQuestionnaire>
</ArticleMultipleQuestionnaire>

In many real-world projects, you don't need a brand-new module. Instead, you want to **extend an existing feature inside a module**; for example, in the product module (`sw-product`), you may want to add a new tab, extend a detail view, or inject logic into an existing page.

This leads to an important clarification: By default, you **cannot extend a module itself**. A module is only a structural container that bundles routes, pages, views, ACL, and components.

What is extendable are the **building blocks inside the module**. You can safely override/extend components, pages, views, routes, or ACL entries.

### What to Pay Attention To When Extending Core Modules

Extending existing administration features is powerful, but you should choose the smallest suitable entry point first.

Before you override an existing part of the administration, check whether there is a more specific extension point:

- Can you add your own module or page instead of changing a core one?
- Can you add a view, tab, route, or child component?
- Can you use an existing Twig block and keep most of the original template?
- Can you extend a component and add behavior instead of replacing the original implementation?

Use overrides when you really need to replace an existing part. Overrides are heavier to maintain because they can conflict with other plugins and may need extra review when Shopware changes the original component, page, or view.

Use these rules as a decision guide:

**Use the correct extension type:**

- Use Twig blocks `{% block %}` when you only need to change a specific template area.
- Use `Shopware.Component.extend()` when you want to add logic while keeping the original component as the base.
- Use `Shopware.Component.override()` only when you need to replace an existing component, page, or view configuration.

**Know what you are extending/overriding:** Always identify the correct component/page/view path in the Shopware core: `src/Administration/Resources/app/administration/src/module/<module>/<page|view|component>/`

**Use the mirroring principle:** You already know the mirroring principle from the storefront development. You can use the same approach to extend or override core modules. A good pattern is to add `-override` in the dedicated folder name.

**Always register your extensions before the core module is instantiated:** This is automatically handled when the files are placed under `Resources/app/administration/src/module/...` inside your plugin.

### Example: Override A View of the `sw-product-detail` Component

The following example shows an override on purpose. It is useful to understand the mechanism, but it should not be your automatic first choice. In real projects, first look for a smaller extension point that achieves the same result with less maintenance risk.

You already know how to **extend** a component. Before you continue, let's briefly recall how the `Shopware.Component.extend()` method works:

<ArticleMultipleQuestionnaire>
  <ArticleQuestionnaire>
    <ArticleQuestionnaireQuestion>What are the three parameters of `Shopware.Component.extend(param1, param2, param3)` represent?</ArticleQuestionnaireQuestion>
    <ArticleQuestionnaireAnswer correct>Param1 = Name of the new component. Param2 = Name of the base component, Param3 = component configuration object of the new one</ArticleQuestionnaireAnswer>
    <ArticleQuestionnaireAnswer>Param1 = Name of the base component. Param2 = Name of the new component, Param3 = A template import</ArticleQuestionnaireAnswer>
  </ArticleQuestionnaire>
</ArticleMultipleQuestionnaire>

Now, let's look at how to **override a view** inside the product module. You will extend the view `sw-product-detail-base`, which is the main layout of the product detail page.

First, create a new folder `sw-product-detail-base-override` under `[your_plugin]/src/Resources/app/administration/src/module/sw-product/view`:

Inside this folder, create two files: the `index.js` and the `sw-product-detail-base.html.twig`.

In the Twig file, override an existing block (e.g., `sw_product_detail_base`):

```twig
{% block sw_product_detail_base %}
    <div>Hello, I'm an override! </div>
{% endblock %}
```

And in the index.js file, override the component:

```js
import template from './sw-product-detail-base.html.twig';

Shopware.Component.override(
  'sw-product-detail-base', // The View Name from the core we want to override 
  { template: template } // Our new template to override the core template
);
```

Finally, import your override in the `main.js` file (`[your_plugin]/src/Resources/app/administration/src/main.js`), so Shopware can register it:

```js
import './module/sw-product/view/sw-product-detail-base-override';
```

Build the administration again:

```bash
bin/build-administration.sh
```

Shopware CLI equivalent: `shopware-cli project admin-build`.

To see the result, open the administration of your local shop and navigate to any product, open its detail view. You should now see your override instead of the default one.

**Before**

![Before override](assets/images/administration-product-general.jpg)

**After the override**

![After override](assets/images/administration-product-general-override.jpg)

<Callout title="Load the Original Template" type="info">

When overriding a template block, you can still include the original content by calling `{% parent %}` before (or after) overriding the block with your own content.

Using `{% parent %}` helps you keep the original markup, but it does not remove the maintenance cost of an override. You still depend on the structure of the original template.

When Shopware is updated, compare the original core block with your overridden block again. If the core template changed around that block, your override may still work technically but no longer match the intended structure.

</Callout>

You might be asking yourself: **What is then the difference between overriding a component (even with using parent) and extending it?**

The key distinction is:

- **Overriding** replaces part of an existing component, view, or page configuration. Use it carefully because your code depends on the original structure.
- **Extending** creates a **new component** that **inherits** from the original one. This allows you to add or override **JavaScript logic** while keeping the parent as the base.

## Summary

In this learning unit, you learned how to structure larger administration modules in Shopware and how to extend existing administration features through suitable entry points.

By now, you should be able to:

- Apply the recommended folder structure for large administration modules, including pages, views, snippets, and ACL rules.
- Differentiate between pages, views, and components and know when to use each layer.
- Understand that a module itself cannot be extended but its parts can be extended or overridden.
- Decide when a specific extension point is enough and when an override is really needed.
- Override an existing administration view by customizing a template block.

Well done! With this understanding, you are ready to build maintainable module architectures and confidently customize existing administration features in a clean and update-safe way.
