How to Create Custom Modules in Shopware 6

In this guide, you’ll learn to Create Custom Modules in Shopware 6.

Prerequisites
This guide does not explain how to create a new plugin for Shopware 6. Head over to our Plugin base guide to learn how to create a plugin at first:
(https://developer.shopware.com/docs/guides/plugins/plugins/plugin-base-guide)

Create index.js file


The first step is creating a new directory

/src/Resources/app/administration/src/module/ict-example.

You can store your own modules files in there. Create a new file called index.js in there. it is the main file for your custom module.

Note:- This is necessary because Shopware 6 is automatically requiring an index.js file for each module.

The custom module directory isn’t known to Shopware 6 yet. The entry point of your plugin is the main.js file. That’s the file you need to change now so that it loads your new module. For this, simply add the following line to your main.js file:

/src/Resources/app/administration/src/main.js
import ‘./module/ict-example’;

Your module’s index.js will be executed.

Registering the module


index.js is still empty now, so let’s create a new module. This is technically done by calling the registerModule method of our ModuleFactory, but you’re not going to use this directly.

You’re using Shopware.Module.register() method, but why is that?

Shopware is a global object created for third-party developers. It is mainly the bridge between the Shopware Administration and our plugin. The Module object comes with a register helper method to easily register your module. The method needs two parameters to be set, the first one being the module’s name, the second being a javascript object, which contains your module’s configuration.

{% code title=”/src/Resources/app/administration/src/module/ict-example/index.js” %}Shopware.Module.register(‘ict-example’, {

// configuration here

});

{% endcode %}

Configuring the module


You can configure a couple of things.

  1. The color of your module. Each module needs a primary color, which will be used on specific accents and locations throughout your module. To name a few, it’s the color of the main icon of the module, the tag in the global search input, and the accent color of the smart bar.
  2. You can see here which icons are available in Shopware 6 by default. In our case here, let’s say we use the icon default-shopping-paper-bag-product, which will also be used for the module.
  3. {% hint style=”danger” %} This is not the icon being used for a menu entry! The icon for that needs to be configured separately. Please refer to the Add a menu entry guide for more information on this topic. {% endhint %}
  4. You’re able to configure a title here, which will be used for the actual browser title. Just add a string for the key title. This will be the default title for your module, you can edit this for each component later on.
  5. The description is the last basic information you should set here, which will be shown as an empty state. That means the description will be shown e.g. when you integrated a list component, but your list is empty as of now. In that case, your module’s description will be displayed instead.
  6. e.g. ict-example-list for the list of your module, ict-example-detail for the detail page, and ict-example-create for creating a new entry. Those routes are configured as an object in a property named routes. We will cover that in the next paragraph.

Set up additional meta info

You should have got a menu entry then. The related routes are also set up already and linked to components, which will be created in the next main step. There’s a few more things we need to change in the configurations though that you should add to your module, such as a unique name and a type.

example:{% code title=”/src/Resources/app/administration/src/module/ict-example/index.js” %}Shopware.Module.register(‘ict-example’, {

type: ‘plugin’,

name: ‘Example’,

title: ‘ict-example.general.mainMenuItemGeneral’,

description: ‘sw-property.general.descriptionTextModule’,

color: ‘#ff3d58’,

icon: ‘default-shopping-paper-bag-product’,

{% endcode %}

The name should be a technical unique one, the type would be ‘plugin’ here. When it comes to this type, there are two options in Shopware: core and plugin. So every third-party module should use a plugin. To give a little context: Looking at module.factory inside registerModule the plugin type is the only case that is being checked and has some different behavior. So it is more a convention and not a real validation that throws an error when the type is divergent from these options.

Implementing snippets

Create a new directory snippet in your module’s directory and in there two new files: de-DE.json and en-GB.jsonThen, when each file contains your translations as an object, you only have to import them into your module again.

{% code title=”/src/Resources/app/administration/src/module/ict-example/index.js” %}

[…]

import deDE from ‘./snippet/de-DE’;

import enGB from ‘./snippet/en-GB’;

Shopware.Module.register(‘ict-example’, {

snippets: {

‘de-DE’: deDE,

‘en-GB’: enGB

},

});

{% endcode %}

Create the first translation, which is for your menu’s label. It’s key should be something like this: ict-example.general.mainMenuItemGeneral

Thus open the snippet/en-GB.json file and create the new object in there. The structure here is the same as in the first example, just formatted as json file.

To translate the description or the title, add those to your snippet file as well and edit the values in your module’s description and title. The title will be the same as the main menu entry by default.

This should be your snippet file now:

{

“ict-example”: {

“general”: {

“mainMenuItemGeneral”: “My custom module”,

“descriptionTextModule”: “Manage this custom module here”

}

}

}

Build the administration

Shopware 6 is looking for a main.js file in your plugin. Its contents get minified into a new file named after your plugin and will be moved to the public directory of the Shopware 6 root directory. Given this plugin would be named “IctAdministrationNewModule”.

The bundled and minified javascript code for this example would be located under /src/Resources/public/administration/js/ict-administration-new-module.js, once you run the command following command in your Shopware root directory:

{% tabs %} {% tab title=”Development template” %}

./psh.phar administration:build

{% endtab %}

{% tab title=”Production template” %}

./bin/build-administration.sh

{% endtab %} {% endtabs %}

{% hint style=”info” %} Your plugin has to be activated for this to work. {% endhint %}

Make sure to also include that file when publishing your plugin! A copy of this file will then be put into the directory /public/bundles/administration/ictadministrationnewmodule/administration/js/ict-administration-new-module.js.

Your minified javascript file will now be loaded in production environments.

Special: Case Settings

Link your module to settings

Create a module concerning settings, you might want to link your module in the settings section of the administration.

You can add the settings item option to the module configuration as seen below:

{% code title=”/src/Resources/app/administration/src/module/ict-example/index.js” %}
import ‘./page/ict-plugin-list’;

import ‘./page/ict-plugin-detail’;

Shopware.Module.register(‘ict-plugin’, {

settingsItem: [{

group: ‘plugin’,

to: ‘ict.plugin.list’,

icon: ‘default-object-rocket’,

name: ‘ict-example.general.mainMenuItemGeneral’

}]

});

{% endcode %}

The group property targets the group section, and the item will be displayed in ‘shop’, ‘system’ and ‘plugins’ sections.

The to gets the link path of the route. The icon contains the icon name which will be displayed.

Add custom settings card

You can even provide custom setting cards that are either placed in shop, system or plugin tab. This can be achieved by adding the key settings item to your module object:

settingsItem: [{ // this can be a single object if no collection is needed
to: ‘custom.module.overview’, // route to anything

group: ‘system’, // either system, shop or plugins

icon: ‘default-object-lab-flask’,

iconComponent: YourCustomIconRenderingComponent, // optional, this overrides icon attribute

id: ”, // optional, fallback is taken from module

name: ”, // optional, fallback is taken from module

label: ”, // optional, fallback is taken from module

}]

Example for the final module

Your final module:

{% code title=”/src/Resources/app/administration/src/module/ict-example/index.js” %}
import ‘./page/ict-example-list’;

import ‘./page/ict-example-detail’;

import ‘./page/ict-example-create’;

import deDE from ‘./snippet/de-DE’;

import enGB from ‘./snippet/en-GB’;

Shopware.Module.register(‘ict-example’, {

type: ‘plugin’,

name: ‘Example’,

title: ‘ict-example.general.mainMenuItemGeneral’,

description: ‘sw-property.general.descriptionTextModule’,

color: ‘#ff3d58’,

icon: ‘default-shopping-paper-bag-product’,

snippets: {

‘de-DE’: deDE,

‘en-GB’: enGB

},

routes: {

list: {

component: ‘ict-example-list’,

path: ‘list’

},

detail: {

component: ‘ict-example-detail’,

path: ‘detail/:id’,

meta: {

parentPath: ‘ict.example.list’

}

},

create: {

component: ‘ict-example-create’,

path: ‘create’,

meta: {

parentPath: ‘ict.example.list’

}

}

},

navigation: [{

label: ‘ict-example.general.mainMenuItemGeneral’,

color: ‘#ff3d58’,

path: ‘ict.example.list’,

icon: ‘default-shopping-paper-bag-product’,

position: 100

}]

});

{% endcode %}

Bhavya Shah is a Business Analyst at iCreative Technologies. He specializes in the eCommerce consulting for all business domains. He is working hand-in-hand with developers and clients to produce requirements and specifications that accurately reflect business needs and are technologically achievable.