Skip to content

Make <vc:widget> work in theme and plugin views again - #993

Merged
KrzysztofPajak merged 2 commits into
developfrom
fix/nordic-product-view-components
Oct 25, 2026
Merged

KrzysztofPajak merged 2 commits into
developfrom
fix/nordic-product-view-components

Conversation

@KrzysztofPajak

@KrzysztofPajak KrzysztofPajak commented Oct 25, 2026 •

Copy link
Copy Markdown
Member

Type: bugfix

Issue

<vc:widget> stopped working in every theme and plugin view after #922. In the Nordic theme this is visible on any product page, e.g. /ember-ceramic-pour-over-dripper: the product overview (name, price, add to cart) drops below the picture instead of sitting next to it.

<vc:...> tags are tag helpers that Razor generates at compile time for the view components of every assembly registered with @addTagHelper. WidgetViewComponent lived in Grand.Web. #922 removed @addTagHelper *, Grand.Web from plugin and theme _ViewImports on the assumption that Grand.Web has no tag helpers, and it made a plugin reference to Grand.Web a build error (GRAND001). From then on, Razor emitted <vc:widget> in any plugin or theme view as a literal unknown HTML element, with no build error or warning:

  • every widget zone written as <vc:widget> in a theme stopped rendering its widgets. That is the form used throughout the default views, so any view copied from them into a theme is affected.
  • in Nordic, the empty <vc:widget> elements inside .nordic-pd__main got width: 100% from Bootstrap's .row > * and pushed the overview column onto a new line.
  • for the same reason, Nordic's Simple product layout lost its also-purchased, related, similar and recommended product sections (<vc:products-also-purchased> etc.).

Solution

  • WidgetViewComponent moves from Grand.Web to Grand.Web.Common. Every plugin and theme already registers @addTagHelper *, Grand.Web.Common, and Grand.Web.Common is an application part of the host. As a result, <vc:widget> works again in all plugin and theme views without a reference to Grand.Web, and the host views keep working because they register both assemblies. The component's code is unchanged.
  • WidgetModel moves along with it. Its namespace stays Grand.Web.Models.Cms, as Move storefront view models into Grand.Web.Models #922 did for the other models. The storefront and theme _ViewImports import that namespace, and WidgetModel was its only type.
  • WIDGET_MODEL_KEY moves from CacheKeyConst (Grand.Web) to CacheKey (Grand.Infrastructure). The key string is unchanged and only the component uses it.
  • The component's unit tests move to Grand.Web.Common.Tests.
  • The product-list components (ProductsAlsoPurchased, RelatedProducts, SimilarProducts, RecommendedProducts) depend on Grand.Web handlers and cannot move. Nordic's Simple layout now invokes them by name with Component.InvokeAsync, as its Grouped layout already did.
  • .ai/skills/theme-creation.md explains which <vc:...> tags work in a theme and how to rewrite the others.

Breaking changes

  • WidgetViewComponent is now Grand.Web.Common.Components.WidgetViewComponent (was Grand.Web.Components). Views address it by name, so only code that references the type directly is affected.
  • CacheKeyConst.WIDGET_MODEL_KEY is now CacheKey.WIDGET_MODEL_KEY.

Testing

  1. Build GrandNode.slnx and run the storefront with the Nordic theme active.
  2. Open a simple product page, e.g. /ember-ceramic-pour-over-dripper. The name, price and add-to-cart block sit to the right of the gallery, and the related products section appears below the tabs.
  3. View the page source of that page and of the home page, a category, /cart and /login: none of them contains <vc:.
  4. Activate a widget plugin that renders in a productdetails_* zone (Nordic uses <vc:widget> there) and confirm that it appears on the product page.
  5. Switch to the Default theme and repeat steps 2 to 4.

#922 dropped the theme's reference to Grand.Web and its
`@addTagHelper *, Grand.Web`, so `<vc:...>` tags for components that
live in Grand.Web stopped compiling into tag helpers. Razor emitted
them as unknown HTML elements: the productdetails_* widget zones and
the also-purchased/related/similar/recommended sections never ran, and
the empty <vc:widget> elements took a full row inside .nordic-pd__main,
pushing the product overview below the gallery.

Component.InvokeAsync resolves the component at runtime, as the rest
of the theme already does, so the theme keeps depending only on
Grand.Web.Models.
Copilot AI balanced review requested due to automatic review settings October 25, 2026 11:20

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota.

…themes

#922 removed `@addTagHelper *, Grand.Web` from plugin and theme
_ViewImports and made a plugin reference to Grand.Web a build error.
View-component tag helpers are generated per registered assembly, so
<vc:widget> in any theme or plugin view compiled to a literal unknown
element: its widget zones rendered nothing, with no build error.

Every plugin and theme registers Grand.Web.Common, which is also an
application part of the host, so the component works there for all of
them. WidgetModel keeps its Grand.Web.Models.Cms namespace, which
storefront and theme _ViewImports import, and the cache key moves to
CacheKey. Nordic's widget zones go back to <vc:widget>; the product-list
components still live in Grand.Web and stay invoked by name.
@KrzysztofPajak KrzysztofPajak changed the title Render Nordic product-page view components by name Make <vc:widget> work in theme and plugin views again Oct 25, 2026
@KrzysztofPajak
KrzysztofPajak merged commit d110aba into develop Oct 25, 2026
9 checks passed
@KrzysztofPajak
KrzysztofPajak deleted the fix/nordic-product-view-components branch October 25, 2026 13:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants