I’m running into an issue with Newsletter Studio on Umbraco v17 related to custom themes, and I’m hoping for some guidance or confirmation whether this is a known problem.
Environment
Umbraco: v17.1.0
Newsletter Studio: v17.0.1
Original setup: Umbraco v13 (same theme worked fine there)
Problem description
After migrating from Umbraco v13 to v17, my customized Newsletter Studio theme no longer behaves as expected.
To rule out migration-related issues, I also:
Set up a completely fresh Umbraco v17.1.0 installation
It can be selected as the theme for a new campaign
What does not work
Any customization inside the theme (e.g. changes in email.cshtml) has no effect
Changes are not reflected:
in the preview iframe
nor in the preview step of the campaign builder
This happens consistently, even in the clean test setup
This makes it look as if the theme is selected, but the customized templates are not actually being used during rendering.
Exception encountered
Occasionally, while previewing a campaign, I also run into the following exception.
It looks like a concurrency issue involving AngleSharp’s DOM and non-thread-safe collections:
System.InvalidOperationException: Operations that change non-concurrent collections must have exclusive access.
A concurrent update was performed on this collection and corrupted its state.
The collection's state is no longer correct.
at System.Collections.Generic.Dictionary`2.TryGetValue(TKey key, TValue& value)
at NewsletterStudio.CssInline.AngleSharp.Dom.Element.GetOrCreateCallback(Type type)
at NewsletterStudio.CssInline.AngleSharp.Dom.Element.AttributeChanged(String localName, String namespaceUri, String oldValue, String newValue)
at NewsletterStudio.CssInline.AngleSharp.Dom.Collections.NamedNodeMap.RaiseChangedEvent(Attr attr, String newValue, String oldValue)
at NewsletterStudio.CssInline.AngleSharp.Dom.Collections.NamedNodeMap.SetNamedItemWithNamespaceUri(IAttr item, Boolean suppressMutationObservers)
at NewsletterStudio.CssInline.AngleSharp.Extensions.ElementExtensions.SetOwnAttribute(Element element, String name, String value, Boolean suppressCallbacks)
at NewsletterStudio.CssInline.AngleSharp.Dom.Element.SetAttribute(String name, String value)
at NewsletterStudio.CssInline.PreMailer.PreMailer.SortBySpecificity(Dictionary`2 styles)
at NewsletterStudio.CssInline.PreMailer.PreMailer.MergeStyleClasses(Dictionary`2 styles)
at NewsletterStudio.CssInline.PreMailer.PreMailer.MoveCssInline(...)
at NewsletterStudio.CssInline.CssInlineHelper.InlineCss(...)
at NewsletterStudio.Web.Rendering.DotNetFrameworkCssInliner.InlineCss(...)
at NewsletterStudio.Core.Rendering.EmailRenderer.RenderAsync(IRecipientDataModel recipient)
at NewsletterStudio.Core.Frontend.Campaign.EditorCampaignControllerActions.RenderPreview(Guid campaignKey)
at NewsletterStudio.Web.Controllers.EditorCampaignController.RenderPreview(Guid campaignKey)
Questions
Has anyone successfully used custom Newsletter Studio themes on Umbraco v17?
Are there breaking changes in v17 regarding how themes or email.cshtml are resolved?
Is the AngleSharp exception a known issue or related to parallel rendering of previews?
Any recommendations for debugging or configuration changes I might be missing?
Any help or pointers would be greatly appreciated.
Thanks in advance!
Seems like there are two issues at the same time here, let’s tackle them one by one.
There has been some changes to the underlying theme engine e.g. to support docker containers on Linux. Are you saying that you are following this guide Themes | Documentation | Newsletter Studio but that it does not work?
Do you mind telling me a little more about your environment and how you are running the site?
Windows, Mac, Linux? Docker, any “special stuff” going on?
The issue with CssInline.AngleSharp.Dom.Element.GetOrCreateCallback feels familiar. Seems like there is something going on under the hood that I have not seen before. Probably some kind of race condition. It’s most likely related to performance improvements made to speed up rendering, I’ll try to replicate this or at least ensure that the PreMailer is not used in different threads at the same time. Will keep you posted.
Reg. your question about breaking changes, yes - there are changes between v13 and v17 - I would recommend that you skim trough this:
Add 1: Yes, I am following this Guide. I am currently in the process of migrating from v13 to v17, that’s why I run the app locally on Windows 11 using Visual Studio and Kestrel. As I mentioned before, I did that with a blank v17 project as well with the same result.
Your guide suggests using templates from your repository as starting point. I copied the files as mentioned using the desired folder structure and leaving everything unchanged except the name of the theme inside theme.json. So far so good. I can select the theme and use it for a campaign. But any changes to email.cshtml will not show up, even after rebuilding the solution and restarting the app. When I reapply my custom email.cshtml from my previous v13 version, which is already successfully running in production, I even get the mentioned exception.
I think the problem here is that newer versions of .NET does not automatically compile .cshtml files ouside of the /Views/-folder. Probably need to adjust the documentation around this.
Thanks again for letting me know that this solved the problems for you.
First of all, thank you very much for providing all the information around your issues. I’ll follow up here one by one.
I just did a clean install using Umbraco 17.1.0 and Newsletter Studio 17.0.1 using PackageScriptWriter https://psw.codeshare.co.uk/ and followed this guide Themes | Documentation | Newsletter Studio, this worked without me having to change anything in the .csproj etc. So I’m guessing that this might depend on the exact setup and project configuration. With that said, I will make sure to mention your fix in the documentation moving foward.
The concurrency issue is a lot harder to nail down and I would like to ask some more questions just to get a better re-prodcution on the issue and I would be very thankful for your anwsers.
2.1 Can you explain more about when and where you see this issue? Does it happen after a restart or totally random? Does it happen once and then disappear or do you have to restart?
2.2 How does the template look like? Do you have a lot of content, any “special stuff” (macros etc) that is adding new html to the template? if yes please explain
I just released version 17.0.2 and 17.0.3 which hopefully should solve the concurrency issues with Element.GetOrCreateCallback, I manged to re-produce it and provide a fix that I did not manage to break again - hopefully it works for you as well.