Changes to code components in global regions is not loaded until published

Created on 12 March 2025, 22 days ago

Overview

Changes made to code components in global regions are not reflected in the preview until changes to the code component are published, and page is refreshed.

Steps to reproduce

  1. Add a code component to a global region (e.g., header or footer).
  2. Make a change to the code component (e.g., update text or styles).
  3. Save the changes.
  4. Observe that the changes are not visible until the changes are explicitly published, and page is refreshed.

Proposed resolution

User interface changes

🐛 Bug report
Status

Active

Version

0.0

Component

Theme builder

Created by

🇫🇮Finland lauriii Finland

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

Comments & Activities

  • Issue created by @lauriii
  • 🇧🇪Belgium wim leers Ghent 🇧🇪🇪🇺

    So this does not happen when the auto-saved code component is in a content entity's XB field, and only if it is in a PageRegion?

    If so, this would be a missed edge case in 📌 Code Components should render with their auto-saved state(if any) when rendered in the XB UI Active .

    Or are you referring to the PageRegion itself being auto-saved?

  • 🇫🇮Finland lauriii Finland

    So this does not happen when the auto-saved code component is in a content entity's XB field, and only if it is in a PageRegion?

    Yes, exactly. This is what I tried to describe in the steps to reproduce.

  • 🇧🇪Belgium wim leers Ghent 🇧🇪🇪🇺

    25-min deep dive suggests this is because 📌 Code Components should render with their auto-saved state(if any) when rendered in the XB UI Active only modified \Drupal\experience_builder\Controller\ApiLayoutController::buildPreviewRenderable() to do:

    $renderable = $item->toRenderable(TRUE);
    

    which results in a JsComponent::renderComponent(isPreview: TRUE) call, rendering the auto-save (draft).

    But the page regions are not rendered in ::buildPreviewRenderable(), but in \Drupal\experience_builder\Plugin\DisplayVariant\XbPageVariant::build(), where there's still this:

          $fiber = new \Fiber(fn() => $component_tree->toRenderable());
    

    (note the absence of isPreview: TRUE)

    It'll be up to \Drupal\experience_builder\EventSubscriber\PreviewEnvelopeViewSubscriber::onViewPreviewEnvelope() to pass that information to XbPageVariant somehow.

    AFAICT the only feasible approach is to rely on this bit in HtmlRenderer:

          // Instantiate the page display, and give it the main content.
          $page_display = $this->displayVariantManager->createInstance($variant_id, $variant_configuration);
          if (!$page_display instanceof PageVariantInterface) {
            throw new \LogicException('Cannot render the main content for this page because the provided display variant does not implement PageVariantInterface.');
          }
          $page_display
            ->setMainContent($main_content)
            ->setTitle($title)
            ->addCacheableDependency($event);
          // Some display variants need to be passed an array of contexts with
          // values because they can't get all their contexts globally. For example,
          // in Page Manager, you can create a Page which has a specific static
          // context (e.g. a context that refers to the Node with nid 6), if any
          // such contexts were added to the $event, pass them to the $page_display.
          if ($page_display instanceof ContextAwareVariantInterface) {
            $page_display->setContexts($event->getContexts());
          }
    

    IOW: update XbPageVariant to implement ContextAwareVariantInterface. Then do something like \Drupal\display_variant_test\EventSubscriber\TestPageDisplayVariantSubscriber::onSelectPageDisplayVariant() to provide a yet-to-be-created "XB preview" context, which can then be respected by XbPageVariant, and which would result in $page_display->setContrexts(['xb_preview' => TRUE]);.

    The only alternative I see: add a #xb_preview => TRUE key-value pair to the "main content", which then is detected by XbPageVariant.

  • 🇧🇪Belgium wim leers Ghent 🇧🇪🇪🇺

    ⚠️ AFAICT this also affects the component preview upon hovering the list of available components:

    diff --git a/src/Plugin/ExperienceBuilder/ComponentSource/BlockComponent.php b/src/Plugin/ExperienceBuilder/ComponentSource/BlockComponent.php
    index 4fbac989c..adb573f8d 100644
    --- a/src/Plugin/ExperienceBuilder/ComponentSource/BlockComponent.php
    +++ b/src/Plugin/ExperienceBuilder/ComponentSource/BlockComponent.php
    @@ -302,7 +302,7 @@ final class BlockComponent extends ComponentSourceBase implements ContainerFacto
           return ['build' => []];
         }
     
    -    return ['build' => $this->renderComponent([], $component->uuid())];
    +    return ['build' => $this->renderComponent([], $component->uuid(), TRUE)];
       }
     
       /**
    diff --git a/src/Plugin/ExperienceBuilder/ComponentSource/GeneratedFieldExplicitInputUxComponentSourceBase.php b/src/Plugin/ExperienceBuilder/ComponentSource/GeneratedFieldExplicitInputUxComponentSourceBase.php
    index c55528b5b..39653166a 100644
    --- a/src/Plugin/ExperienceBuilder/ComponentSource/GeneratedFieldExplicitInputUxComponentSourceBase.php
    +++ b/src/Plugin/ExperienceBuilder/ComponentSource/GeneratedFieldExplicitInputUxComponentSourceBase.php
    @@ -603,7 +603,7 @@ abstract class GeneratedFieldExplicitInputUxComponentSourceBase extends Componen
     
         return [
           'source' => (string) $this->getSourceLabel(),
    -      'build' => $this->renderComponent([self::EXPLICIT_INPUT_NAME => $default_props_for_default_markup], $component->uuid()),
    +      'build' => $this->renderComponent([self::EXPLICIT_INPUT_NAME => $default_props_for_default_markup], $component->uuid(), TRUE),
           // Additional data only needed for SDCs.
           // @todo UI does not use any other metadata - should `slots` move to top level?
           'metadata' => ['slots' => $this->getSlotDefinitions()],
    
  • 🇧🇪Belgium wim leers Ghent 🇧🇪🇪🇺

    Extracting #5 into a separate issue, because as @f.mazeikis and @longwave pointed out: there's cache invalidation challenges there. So extracted A) preview-on-hover into 🐛 Changes to code components are not visible in preview-on-hover-component-list until published Active .

Production build 0.71.5 2024