Sub-theme
CivicTheme must never be modified directly. Your sub-theme inherits everything from CivicTheme and is where all custom work happens — overriding components, adding new ones, and adjusting styles. The build system merges your sub-theme's components with the base theme's components at compile time, so your overrides take priority automatically.
Prerequisites
CivicTheme installed and sub-theme generated (see GovCMS SaaS installation or Drupal installation)
NodeJS 22+ and NPM 10+ available
Front-end assets built successfully (
npm run build)
Creating a sub-theme
CivicTheme provides a starter theme and a script to generate a child theme.
Run the following command from within the civictheme theme directory:
php civictheme_create_subtheme.php <theme_machine_name> "Human theme name" "Human theme description" /path/to/theme_machine_nameThis generates a sub-theme in path/to/theme_machine_name with everything ready to be installed and compiled.
Enabling the sub-theme
Enable the theme in UI or with Drush:
drush theme:enable theme_machine_nameCompiling assets
Run the following command from within your sub-theme directory:
NodeJS version >=22 is required to compile front-end assets.
Directory structure
The sub-theme creation script generates the following project scaffold:
Key directories
components/— where you override existing CivicTheme components or add new ones. The atomic design hierarchy (00-base through 04-templates) mirrors CivicTheme's own structure.assets/— where you place your site's logos, icons, fonts, and background images.templates/— where you add Drupal-specific Twig template overrides that map Drupal data to components.components/variables.base.scssandcomponents/variables.components.scss— where you override CivicTheme's design tokens (colors, spacing, typography) without touching the base theme.
Library system
Your sub-theme declares its compiled assets as Drupal libraries in <theme_name>.libraries.yml. The key library is global, which loads your compiled CSS and JavaScript on every page.
The sub-theme's info.yml file uses libraries-override to replace CivicTheme's compiled assets with your sub-theme's compiled assets. This is how the build system's merged output takes over from the base theme:
You should not need to modify these library definitions unless you are adding entirely new Drupal libraries (separate from the component system).
Placeholder assets
The starter kit ships with placeholder logos, backgrounds, and a screenshot. Replace these with your site's actual assets:
Logos — replace files in
assets/logos/. CivicTheme supports multiple logo variants for header and footer, light and dark themes, and desktop and mobile sizes.Backgrounds — replace files in
assets/backgrounds/.Favicon — update via the Drupal theme settings page.
Screenshot — replace
screenshot.png(shown in Drupal's Appearance page).
After replacing assets, rebuild:
Troubleshooting
Build fails with rsync errors
The build system uses rsync to merge component directories. Ensure rsync is installed and available on your system. On macOS it is included by default; on Windows, use WSL or install rsync separately.
Storybook shows blank page or missing components
Check the browser console for errors
Ensure
npm run distcompleted successfully before starting StorybookVerify that
dist/constants.jsonexists (Storybook reads icon and asset lists from it)
Changes not appearing in Drupal
Clear Drupal caches:
drush crConfirm you ran
npm run distafter making changesCheck that your sub-theme (not the base CivicTheme) is set as the default theme
Node version mismatch
The sub-theme includes an .nvmrc file specifying the required Node version. Use nvm use to switch to the correct version before running any npm commands.
Last updated
Was this helpful?