Component library missing when rendered via Drupal.theme (via JS not via Twig)

Created on 16 October 2024, 4 months ago

Problem/Motivation

Component library is missing when it is not rendered via Twig.

If rendered with Drupal JavaScript API - such as a custom Drupal.theme.myComponent for instance - the component's library is not loaded.

Steps to reproduce

  • Create a single-directory component in a module
  • Render the component programmatically
  • Attach the output in drupalSettings
  • Create a custom Drupal.theme.myComponent function and consume the output
  • Call the Drupal.theme
  • Result: the component Twig is rendered but the library is missing (i.e. no CSS no JS)

Proposed resolution

TBD

Remaining tasks

TBD

Feature request
Status

Active

Version

11.0 🔥

Component

single-directory components

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @matthieuscarset
  • The scenario which leads me to this issue was the following: How to use a SDC to theme Drupal messages individually?

    Since Drupal 10.3 and this bug in particular 🐛 10.3 upgrade now missing status-message theme sugestions Active , there is no way for individual message to use a Twig template. Each Drupal messages are rendered via Drupal.theme.message.

    Consequently there is no other choice than implementing a custom Drupal.theme.message method in a custom theme or a custom module and - if one wants to use a SDC to render messages - I don't see any other way than to pass the component output to drupalSettings to be reused in JS.

    Example code in this snippet: https://git.drupalcode.org/-/snippets/214

  • 🇫🇷France pdureau Paris

    Each Drupal messages are rendered via Drupal.theme.message.

    So, maybe we need to fix the root cause instead of introducing a workaround: 🐛 10.3 upgrade now missing status-message theme sugestions Active

  • This is "the root cause" for this specific scenario (e.g. using SDC to theme Messages).

    The feature request is still relevant for any other use cases such as printing mycomponent:xyz using a custom Drupal.theme.xyz in JS

  • 🇫🇷France pdureau Paris

    So, we need to add attach the asset library from ComponentElement render element in preRenderComponent() method?

    The asset library is already attached in ComponentNodeVisitor:

        $print_nodes[] = new PrintNode(new FunctionExpression(
          new TwigFunction('attach_library', [$env->getExtension(TwigExtension::class), 'attachLibrary']),
          new Node([new ConstantExpression($component->getLibraryName(), $line)]),
          $line
        ), $line);
    

    It would be the dream to remove ComponentNodeVisitor and move all the logic to ComponentElement but it is not possible yet because it will be a compatibility break for the poor souls using Twig include or embed to call a component template.

    So, if we add asset library attachment in ComponentElement, the library will be attached twice. It is supposed to be OK because the asset library API takes care of this, but we need to be sure there is no side effects.

  • 🇳🇿New Zealand quietone

    Changes are made on on 11.x (our main development branch) first, and are then back ported as needed according to our policies.

Production build 0.71.5 2024