Shadowing Header component ignored in Volto 18 + pnpm workspaces monorepo

Hello everyone,

I'm struggling to make component shadowing work for the Header component in a Volto 18 project structured as a pnpm monorepo. Even after trying standard customizations and razzle.config.js aliases, the original Header persists and my custom file is ignored.

Environment:

  • Volto: 18.28.2

  • Plone: 6.1.3

  • Package Manager: pnpm (workspaces enabled)

  • OS: Linux (WSL2)

Project Structure: My project has a local core package structure: frontend/core/packages/volto (It seems the core is local/symlinked) frontend/packages/volto-intranet-crfgo (My local add-on)

What I have tried:

  1. Standard Shadowing in Root: Created the file at: frontend/src/customizations/volto/components/theme/Header/Header.jsx (I also tried @plone/volto/... and removing the namespace, but no success).

  2. Add-on Shadowing: Created the file inside my local package: packages/volto-intranet-crfgo/src/customizations/volto/components/theme/Header/Header.jsx And added "volto": { "customizationPaths": ["src/customizations"] } to the add-on's package.json.

  3. Razzle Config Hard Alias (The "Nuclear" option): I tried to force the resolution in razzle.config.js to bypass symlink issues:

    const path = require('path');
    module.exports = {
      modify: (config, { target, dev }, webpack) => {
        config.resolve.symlinks = false; // Tried setting this to false
    
        // Tried forcing the alias directly
        config.resolve.alias['@plone/volto/components/theme/Header/Header'] = 
          path.resolve(__dirname, 'src/customizations/volto/components/theme/Header/Header.jsx');
    
        return config;
      },
    };
    
    

The Result: The build runs successfully, but the default Volto Header is always rendered. I added a console.log and a red border to my custom Header, but they never show up, meaning the file is not even being loaded by Webpack.

Question: Is there a specific configuration for pnpm workspaces in Volto 18 that changes how shadowing paths are resolved? Since my Volto core seems to be a local package (symlinked), is Webpack resolving the physical path and bypassing the aliases?

Any guidance on how to debug the module resolution or the correct path structure for this specific monorepo setup would be greatly appreciated.

Thanks in advance!

@Fernandodsb did you follow Shadow a component or module — Plone Documentation v6 carefuly?

I can see that neither of your approaches are the ones described in there.

Please, could you follow it and report back? Feedback from documentation is important.

Thanks!