Create a Volto theme add-on#

You can create a Volto theme add-on, keeping it separate from your project files. By making your Volto theme add-on pluggable, you can deploy the same theme in different projects. You can even create themes that depend on conditions that you inject at build time.

The file volto.config.js provides the ability to programmatically declare add-ons and the active theme. See Programmatically define the active add-ons and theme for more information. For convenience, it can also be set via a THEME environment variable.

  1. In your volto.config.js file at the root of your project, add a theme key with the value of your theme's name.

    module.exports = {
      addons: [],
      theme: 'volto-my-theme'
    };
    

    Alternatively, you can add a theme key in your package.json project.

    "theme": "volto-my-theme"
    

    Or you can set the theme name through the THEME environment variable.

    THEME='volto-my-theme' pnpm start
    
  2. Create a directory src/theme in your add-on. Inside that directory, create a new file theme.config, adding the following content, but replacing <name_of_your_theme> with your add-on name.

    /*******************************
            Theme Selection
    *******************************/
    
    /* To override a theme for an individual element specify theme name below */
    
    /* Global */
    @site        : 'pastanaga';
    @reset       : 'pastanaga';
    
    /* Elements */
    @button      : 'pastanaga';
    @container   : 'pastanaga';
    @divider     : 'pastanaga';
    @flag        : 'pastanaga';
    @header      : 'pastanaga';
    @icon        : 'pastanaga';
    @image       : 'pastanaga';
    @input       : 'pastanaga';
    @label       : 'pastanaga';
    @list        : 'pastanaga';
    @loader      : 'pastanaga';
    @placeholder : 'pastanaga';
    @rail        : 'pastanaga';
    @reveal      : 'pastanaga';
    @segment     : 'pastanaga';
    @step        : 'pastanaga';
    
    /* Collections */
    @breadcrumb  : 'pastanaga';
    @form        : 'pastanaga';
    @grid        : 'pastanaga';
    @menu        : 'pastanaga';
    @message     : 'pastanaga';
    @table       : 'pastanaga';
    
    /* Modules */
    @accordion   : 'pastanaga';
    @checkbox    : 'pastanaga';
    @dimmer      : 'pastanaga';
    @dropdown    : 'pastanaga';
    @embed       : 'pastanaga';
    @modal       : 'pastanaga';
    @nag         : 'pastanaga';
    @popup       : 'pastanaga';
    @progress    : 'pastanaga';
    @rating      : 'pastanaga';
    @search      : 'pastanaga';
    @shape       : 'pastanaga';
    @sidebar     : 'pastanaga';
    @sticky      : 'pastanaga';
    @tab         : 'pastanaga';
    @transition  : 'pastanaga';
    
    /* Views */
    @ad          : 'pastanaga';
    @card        : 'pastanaga';
    @comment     : 'pastanaga';
    @feed        : 'pastanaga';
    @item        : 'pastanaga';
    @statistic   : 'pastanaga';
    
    /* Extras */
    @main        : 'pastanaga';
    @custom      : 'pastanaga';
    
    /*******************************
                Folders
    *******************************/
    
    /* Path to theme packages */
    @themesFolder : '~volto-themes';
    
    /* Path to site override folder */
    @siteFolder  : "<name_of_your_theme>/theme";
    
    /*******************************
             Import Theme
    *******************************/
    
    @import (multiple) "~semantic-ui-less/theme.less";
    @fontPath : "~volto-themes/@{theme}/assets/fonts";
    
    .loadAddonOverrides() {
      @import (optional) "@{siteFolder}/@{addon}/@{addontype}s/@{addonelement}.overrides";
    }
    
    /* End Config */
    
  3. Declare the theme as an add-on by adding its name to the value for the addons key in either volto.config.js or package.json in your project.

  4. After starting Volto, the theme should be active. Now you can add overrides to the default theme in src/theme, the same as you would in a project.

  5. Finally, you can safely delete your project's original theme folder, since the one in the add-on will take precedence, and a project can only have one active theme at a time.

Using your own theming escape hatch#

Volto theming uses Semantic UI theming capabilities to define and extend a theme for your site. However, while maintaining and playing well with the Semantic UI Volto base, you can use a traditional CSS approach using the LESS preprocessor-based extras escape hatch.

At the same time, you can either discard or complement the extras escape hatch and add your own, by customizing the theme.js module in Volto.

import 'semantic-ui-less/semantic.less';
import '@plone/volto/../theme/themes/pastanaga/extras/extras.less';

// You can add more entry points for theming
import '@kitconcept/volto-light-theme/theme/main.scss';

Customizing the base theme is a special use case in Volto. To begin, add a ./@root/theme.js file structure in your customizations folder in your add-on or project.

You may want to do this to create a completely new theming experience adapted to your way of doing things that do not match the current Volto theming experience. For example, if you want to use another preprocessor in the theme, such as SCSS. Or perhaps your client requires the base consist entirely of pre-made components based on another library beside Semantic UI. See Using third party libraries and themes other than semantic-ui for an example of a custom theme escape hatch.

While building your own escape hatch for theming, you can use the preprocessor of your choice, while maintaining the "base" Volto theme, but customizing it using the resultant CSS.

You can see an example of such a theme in Volto Light Theme.

Modify a custom theme from another add-on#

Sometimes you have a custom theme that you want to reuse through all your projects, but with some differences, maintaining the base. Usually, the only option would be to use an add-on that adds more CSS to the base theme, using imports that will load after the theme. However, there is a problem with this approach. You cannot use existing theme variables, including breakpoints, on these new styles. Similarly, it gets somewhat detached from the normal flow of the loaded theme. The same applies for add-ons, as they are detached from the current theme. You could use a Semantic UI approach for making this work, but then it's bound to Semantic UI.

Warning

This is only possible when using your own escape hatch, and works only with SCSS-based themes, and not with Semantic UI themes, since it enables a couple of entry points that only support SCSS files. For an example of how it could be used, see Volto Light Theme.

If your custom escape hatch defines a custom theme using SCSS, you can take advantage of this feature. Although not limited to this, it would be possible to extend this feature to add more entry points, using another preprocessor or theming approach.

This feature enables two entry point files, _variables.scss and _main.scss. From your add-on code, you can extend an existing theme by creating a file corresponding to each entry point:

  • ./src/theme/_variables.scss

  • ./src/theme/_main.scss

Variables#

You can use the entry point addonsThemeCustomizationsVariables to modify the original variables of the currently loaded theme by adding the entry point before the theme variable definitions. In the theme, it should be imported as shown below.

@import 'addonsThemeCustomizationsVariables';
@import 'variables';
@import 'typography';
@import 'utils';
@import 'layout';

Warning

Following SCSS best practices, your theme variables should be "overridable" using the !default flag. This assigns a value to a variable only if that variable isn't defined or its value is null. Otherwise, the existing value will be used.

Volto will not only load your add-on entry point files, but it will also detect all the add-ons that have these entry point files, and import them grouped under a single file. It will also automatically add an addonsThemeCustomizationsVariables alias that you can reference from the theme as shown above.

Main#

You can use the entry point addonsThemeCustomizationsMain to add your own style definitions, complementing those in the theme. You should add it after all the CSS of your theme:

@import 'blocks/search';
@import 'blocks/listing';

@import 'temp';

@import 'addonsThemeCustomizationsMain';

/* No CSS beyond this point */

Volto will also detect all the add-ons that have these entry point files, and import them grouped under a single file. It will also automatically add an addonsThemeCustomizationsMain alias that you can reference from the theme as shown above.

Note

It will only work in combination with the theme declaration in volto.config.js or in package.json.