---
title: 'Storefront: Theme Inheritance | Shopware Community Hub'
description: >-
  Learn how Shopware theme inheritance works and how to configure parent and
  child themes, inheritance order, and configuration inheritance using
  theme.json.
canonical_url: 'https://hub.shopware.com/learn/unit/storefront-theme-inheritance'
---

# Storefront: Theme Inheritance

<LearningObjectives>

- Explain the purpose of theme inheritance and when to use base and child themes.
- Configure theme inheritance chains using `theme.json` resource sections  (`views`, `style`, `script`, and `asset`).
- Configure `configInheritance` to inherit theme configuration values from a parent theme.
- Override inherited theme configuration values using the `config` section in a child theme.
- Inspect the Twig rendering order of inherited theme templates with the Symfony Web Profiler.

</LearningObjectives>

# Storefront: Theme Inheritance

Theme inheritance in Shopware allows you to build reusable **base themes** (your corporate design) and create one or more **child themes** on top of it for specific projects or campaigns (e.g., dark mode, Black Friday, B2B variant, Christmas Sale, etc.) without copying the entire theme code.

Instead of duplicating templates, styles, scripts, and assets, Shopware resolves resources through an inheritance chain defined in the `theme.json` file.

In this learning unit, you will learn why theme inheritance is used, how the inheritance chain works, and how to configure it in your theme.

This also clarifies an important boundary from the previous learning unit: Theme inheritance can define which template, style, script, and asset locations are considered, but it does not mean that every file can be replaced just by mirroring a core path. For example, custom icons need their documented icon lookup path or an explicit `sw_icon` call with the right namespace.

## Purpose of Theme Inheritance

Theme inheritance allows you to define a design foundation once (base theme) and create specialized variants (child themes) that override only selected parts.

Typical scenarios include:

- A **company base theme** reused across multiple shops.
- Campaign-specific storefront variants (e.g., Black Friday, Christmas Sale, etc.).
- Country-specific or B2B/B2C variants.
- Long-term maintainability of a shared design system.

Instead of copying templates, styles, scripts, and assets, Shopware resolves resources through an inheritance chain, where the child theme overrides the parent only where necessary.

The key benefit is **less duplication** and a clearer separation between a base design system and project-specific adjustments.

<Callout title="Note" type="info">

In the previous learning path (Frontend Development Essentials), [theming](/learn/course/shopware-frontend-theme-development) is already covered in detail.

This learning unit focuses specifically on **theme inheritance** and how Shopware resolves resources across the inheritance chain.

</Callout>

## Step 1: Create a Parent (Base) Theme

The parent theme contains the reusable visual foundation (layout, styles, shared templates, etc.). Create a base theme:

```bash
bin/console theme:create MyBaseTheme
```

It does not need to be assigned to a sales channel if it is only used as a base theme.

## Step 2: Create a Child Theme

Next, create the child theme that will override specific parts of a base theme:

```bash
bin/console theme:create MyChildTheme
```

The child theme will reference the parent theme inside its `theme.json` file.

## Step 3: Configure Inheritance

Inheritance is configured in the child theme's `theme.json`. You place the parent theme in the relevant sections (`views`, `style`, `script`, and `asset`) **before** the child theme.

```json
{
  "name": "MyChildTheme",
  "author": "Your Name",
  "views": [
    "@Storefront",
    "@Plugins",
    "@MyBaseTheme", // <-- Parent theme
    "@MyChildTheme" // <-- Child theme
  ],
  "style": [
    "@Storefront",
    "@MyBaseTheme", // <-- Parent theme
    "app/storefront/src/scss/base.scss" // <-- Child theme
  ],
  "script": [
    "@Storefront",
    "@MyBaseTheme", // <-- Parent theme
    "app/storefront/dist/storefront/js/my-child-theme.js" // <-- Child theme
  ],
  "asset": [
    "@Storefront",
    "@MyBaseTheme", // <-- Parent theme
    "app/storefront/src/assets" // <-- Child theme
  ]
}
```

Before we proceed, let's remind of the meaning of the order of the items in every attribute in the `theme.json`:

<ArticleMultipleQuestionnaire>
  <ArticleQuestionnaire>
    <ArticleQuestionnaireQuestion>Why the child theme must be placed after the parent theme?</ArticleQuestionnaireQuestion>
    <ArticleQuestionnaireAnswer>It is just a chronicle order, no other meanings</ArticleQuestionnaireAnswer>
    <ArticleQuestionnaireAnswer>Shopware needed this kind of order, otherwise it causes an error</ArticleQuestionnaireAnswer>
    <ArticleQuestionnaireAnswer correct>Entries placed later in the list are loaded with higher priority</ArticleQuestionnaireAnswer>
    <ArticleQuestionnaireAnswer correct>Child theme must be listed after the parent theme to override it</ArticleQuestionnaireAnswer>
  </ArticleQuestionnaire>
</ArticleMultipleQuestionnaire>

Rule of thumb: In each `theme.json` list, entries that come later have higher priority. Therefore, list the parent theme before the child theme.

## Step 4: Inheriting Theme Configuration

Theme configuration values can also be inherited between themes. For that, you can use the `configInheritance` attribute in the `theme.json`.

<Callout title="Important" type="info">

`configInheritance` only affects **theme configuration values** (the `config` section). It does **not** configure template/SCSS/JS/asset inheritance. That inheritance is defined by the entries in `views`, `style`, `script`, and `asset`.

</Callout>

```json
{
  "name": "MyChildTheme",
  "author": "Your Name",
  "views": [
    "@Storefront",
    "@Plugins",
    "@MyBaseTheme", // <-- Parent theme
    "@MyChildTheme" // <-- Child theme
  ],
  "style": [
    "@Storefront",
    "@MyBaseTheme", // <-- Parent theme
    "app/storefront/src/scss/base.scss" // <-- Child theme
  ],
  "script": [
    "@Storefront",
    "@MyBaseTheme", // <-- Parent theme
    "app/storefront/dist/storefront/js/my-child-theme.js" // <-- Child theme
  ],
  "asset": [
    "@Storefront",
    "@MyBaseTheme", // <-- Parent theme
    "app/storefront/src/assets" // <-- Child theme
  ],
  "configInheritance": [ // <-- Config inheritance
    "@Storefront",       // <-- Storefront config (from storefront core)
    "@MyBaseTheme"       // <-- Your parent theme's config
  ]
}
```

This allows the child theme to inherit configuration defaults from its parent and override only selected values in its own `config` section.

## Step 5: Verify the Theme Inheritance

After modifying the inheritance configuration (for example `views/style/script/asset` entries or `configInheritance`), Shopware must reload the theme definitions. Run the following commands:

```bash
bin/console theme:refresh
bin/console cache:clear
bin/console theme:compile
```

## Step 6: Inspect Twig Inheritance in the Symfony Web Profiler

The Symfony Web Profiler helps you verify whether Shopware renders the expected templates from your inheritance chain.

This is especially useful when a child theme is assigned correctly, but you are not sure whether a template is loaded from the child theme, the parent theme, a plugin, or the Storefront core.

### Make the Inheritance Visible

To see the inheritance order clearly, create the same template override in both themes. The child theme and the parent theme will both extend the original storefront template and both will call `parent()`.

In the parent theme, create this file:

```text
custom/plugins/MyBaseTheme/src/Resources/views/storefront/layout/header/logo.html.twig
```

Add the following content:

```twig
{% sw_extends '@Storefront/storefront/layout/header/logo.html.twig' %}

{% block layout_header_logo_inner %}
    {{ parent() }}

    <div class="small text-muted text-center">
        MyBaseTheme parent template
    </div>
{% endblock %}
```

In the child theme, create the same file path:

```text
custom/plugins/MyChildTheme/src/Resources/views/storefront/layout/header/logo.html.twig
```

Add the following content:

```twig
{% sw_extends '@Storefront/storefront/layout/header/logo.html.twig' %}

{% block layout_header_logo_inner %}
    {{ parent() }}

    <div class="small text-primary text-center">
        MyChildTheme child template
    </div>
{% endblock %}
```

Now assign your child theme to the storefront:

```bash
bin/console theme:change
```

Select your child theme and assign it to your storefront sales channel. Then clear the cache:

```bash
bin/console cache:clear
```

Now open the storefront. You should see both marker texts near the header logo:

- The parent marker confirms that the parent theme template is part of the chain.
- The child marker confirms that the child theme overrides the same template and still calls the parent content through `parent()`.

Your result should look similar to this:

![Theme Inheritance: Twig: Header Logo Example](assets/images/theme-inheritance-twig-example.jpg)

### Check the Profiler

You can also verify your Twig inheritance behavior via the Symfony Web Profiler.

Open the Symfony Web Profiler from the toolbar and go to the Twig section.

Look for `storefront/layout/header/logo.html.twig`. The rendered templates list should show that the template is involved in rendering the page.

![Theme Inheritance: Verify via Symfony Web Profiler](assets/images/symfony-profiler-theme-inheritance-twig-example.jpg)

You should see the child theme first, then the parent theme, and finally the original storefront template from Shopware.

This is normal. The Profiler shows the rendering chain from the highest-priority template down to the original template:

- Shopware starts with the active child theme because it has the highest priority in the `views` list.
- The child template calls `parent()`, so Shopware continues with the next template in the chain.
- The parent theme template also calls `parent()`, so Shopware continues again.
- The chain eventually reaches the original storefront template.

This means: The child theme inherits from the parent theme, but during rendering the child override is entered first. `parent()` is what connects the child template back to the parent template and then to the storefront core template.

The Profiler is not just a debugging tool here. It is a way to prove the inheritance chain: If both markers are visible in the storefront and the templates appear in the Twig profiler, the override chain is being rendered.

<Callout title="Maintenance Hint" type="warning">

When you override a Twig block, keep track of the original block you depend on. During Shopware updates, compare your overridden block with the current core template. Even if your override only adds a small change and calls `parent()`, the surrounding core markup can still change.

</Callout>

<Callout title="If You Do Not See the Template" type="warning">

Check these points first:

- The child theme is assigned to the sales channel.
- The child theme lists the parent theme before itself in the `views` section.
- The file path exactly mirrors the storefront template path.
- The template uses `sw_extends`, not plain Twig `extends`.
- The Shopware cache was cleared after creating the template.
- The storefront runs in a development environment where the Symfony Web Profiler is available.

</Callout>

## Example: Overriding Theme Configurations in a Child Theme

After verifying template inheritance in the storefront, let's look at another inheritance layer: Theme configuration.

Assume your parent theme defines reusable configuration fields for your design system. The child theme can inherit these fields and override only the values that should differ for a specific project, campaign, or sales channel.

**Example: Parent Theme Configuration**

The parent theme defines the available configuration fields and their default values:

```json
{
  "name": "MyBaseTheme",
  "author": "Your Name",
  "views": [
    "@Storefront",
    "@Plugins",
    "@MyBaseTheme" // <-- Parent theme
  ],
  "style": [
    "@Storefront",
    "app/storefront/src/scss/base.scss" // <-- Parent theme
  ],
  "script": [
    "@Storefront",
    "app/storefront/dist/storefront/js/my-base-theme.js" // <-- Parent theme 
  ],
  "asset": [
    "@Storefront",
    "app/storefront/src/assets" // <-- Parent theme
  ],
  "config": {
    "fields": {
      "sw-brand-top-bar-color": {
        "type": "color",
        "value": "#0055ff",
        "label": {
          "en-GB": "Top Bar Color",
          "de-DE": "Top Bar Farbe"
        },
        "editable": true
      },
      "sw-brand-icon": {
        "type": "url",
        "value": "/your-logo.svg",
        "editable": true
      },
      "sw-brand-navigation-color": {
        "type": "color",
        "value": "#0055ff",
        "label": {
          "en-GB": "Navigation Color",
          "de-DE": "Navigation Farbe"
        },
        "editable": true
      },
      "sw-brand-footer-color": {
        "type": "color",
        "value": "#0055ff",
        "label": {
          "en-GB": "Footer Color",
          "de-DE": "Footer Farbe"
        },
        "editable": true
      }
    }
  }
}
```

**Example: Child Theme Configuration**

The child theme adds `configInheritance` and points to the parent theme. It can then override selected field values in its own `config` section.

```json
{
  "name": "MyChildTheme",
  "author": "Your Name",
  "views": [
    "@Storefront",
    "@Plugins",
    "@MyBaseTheme", // <-- Parent theme
    "@MyChildTheme" // <-- Child theme
  ],
  "style": [
    "@Storefront",
    "@MyBaseTheme", // <-- Parent theme
    "app/storefront/src/scss/base.scss" // <-- Child theme
  ],
  "script": [
    "@Storefront",
    "@MyBaseTheme", // <-- Parent theme
    "app/storefront/dist/storefront/js/my-child-theme.js" // <-- Child theme
  ],
  "asset": [
    "@Storefront",
    "@MyBaseTheme", // <-- Parent theme
    "app/storefront/src/assets" // <-- Child theme
  ],
  "configInheritance": [ // <-- Config inheritance
    "@Storefront",       // <-- Storefront config (from storefront core)
    "@MyBaseTheme"       // <-- Your parent theme's config
  ],
  "config": {
    "fields": {
      "sw-brand-top-bar-color": {
        "type": "color",
        "value": "#000000", // <-- Override the parent value
        "label": {
          "en-GB": "Top Bar Color",
          "de-DE": "Top Bar Farbe"
        },
        "editable": true
      },
      "sw-brand-icon": {
        "type": "url",
        "value": "/your-logo-campaign-black-friday.svg", // <-- Override the parent value
        "editable": true
      },
      "sw-brand-navigation-color": {
        "type": "color",
        "value": "#000000", // <-- Override the parent value
        "label": {
          "en-GB": "Navigation Color",
          "de-DE": "Navigation Farbe"
        },
        "editable": true
      },
      "sw-brand-footer-color": {
        "type": "color",
        "value": "#000000", // <-- Override the parent value
        "label": {
          "en-GB": "Footer Color",
          "de-DE": "Footer Farbe"
        },
        "editable": true
      }
    }
  }
}
```

Now refresh your themes, assign the child theme to a sales channel if needed, and compile it:

```bash
bin/console theme:refresh
bin/console theme:change # Select your sales channel
bin/console theme:compile
```

<Callout title="Important Note" type="info">

Theme configuration values set in the administration have the highest priority. They override the defaults defined in the `theme.json` file.

</Callout>

In the administration, the parent theme exposes the configuration fields with the default values from its `theme.json`:

![Parent Theme Config](assets/images/parent-theme-config.jpg)

The child theme can use the inherited fields and show its own overridden values:

![Child Theme Config](assets/images/child-theme-config.jpg)

### Usage of Configuration Inheritance

This gives you a useful workflow:

- Define reusable configuration fields in the parent theme.
- Inherit these fields in the child theme through `configInheritance`.
- Override only the values that should be different.
- Adjust the final values in the administration when the sales channel needs a specific setup.

By default, every field under `config` is also available in SCSS as a variable prefixed with `$`. In this example, you can use:

- `$sw-brand-top-bar-color`
- `$sw-brand-icon`
- `$sw-brand-navigation-color`
- `$sw-brand-footer-color`

You can apply these variables in your SCSS (for example, to style the top bar, navigation, and footer):

```scss
.nav-main {
  background-color: $sw-brand-navigation-color;
}
```

The full loop now looks like this:

- `theme.json` defines the configuration fields.
- The administration lets you adjust the values for the theme.
- Shopware exposes the values as SCSS variables.
- You can use those SCSS variables to style your storefront, for example in the navigation.

The key idea is that important design decisions become configurable instead of being hardcoded. For example, if your navigation color, footer color, or status color comes from theme configuration, you can change it in the administration without touching the SCSS code every time.

<Callout title="Tip" type="info">

If you want a config value to be available in Twig but **not** as an SCSS variable, you can disable SCSS export for that field using `scss: false` in `theme.json`.

**Example (`scss: false`)**

```json
{
  "name": "MyChildTheme",
  "configInheritance": [
    "@Storefront",
    "@MyBaseTheme"
  ],
  "config": {
    "fields": {
      "sw-brand-top-bar-color": {
        "type": "color",
        "value": "#000000",
        "editable": true
      },
      "sw-my-api-endpoint": {
        "type": "text",
        "value": "https://example.com",
        "editable": true,
        "scss": false // <-- This line
      }
    }
  }
}
```

- Twig can still read both values in Twig:

   ```twig
   {{ theme_config('sw-brand-top-bar-color') }}
   {{ theme_config('sw-my-api-endpoint') }}
   ```

- SCSS will get `$sw-brand-top-bar-color`, but it will **not** get `$sw-my-api-endpoint`.

</Callout>

## Troubleshooting Checklist

- **My template override is not applied**: Check your `views` order and whether `@Plugins` is included.
- **Assets from the parent theme are “missing”**: Ensure the parent theme is included in the `asset` section.
- **JS from the parent theme is not running**: Ensure the parent theme is included in the `script` section.
- **My SCSS override has no effect**: Verify your override file is loaded before the styles you want to influence.
- **Changes in `theme.json` have no effect**: Run `bin/console theme:refresh` and recompile the theme (`bin/console theme:compile`).
- **My `config` overrides are ignored**: Theme configuration values set in the administration have the highest priority and can override the values defined in `theme.json`.
- **Changes don’t show up**: Clear caches and recompile the theme when necessary.

## Summary

In this learning unit, you learned

- How theme inheritance works in Shopware.
- How to configure inheritance in the `theme.json` file.
- The importance of the order of the items in every attribute.
- How to override theme configurations in a child theme.
- How to verify Twig template inheritance with the Symfony Web Profiler.

With this knowledge, you can now create reusable base themes and customize them for specific projects or campaigns with child themes.
