TempData for Rendering Forms Scripts
Closed this issue · 3 comments
Recently while configuring Cloudflare proxy in front of an Umbraco site, we found pages could not be cached due to the presence of a Set-Cookie
header in the response.
This was found to be caused by including the docs recommended code for rendering form scripts, which was placed in our global layout cshtml. The same applies if using the tag helper approach.
Since ASP.NET Core 2.0 the default TempData provider has used cookies to store values, or can be configured to use Session storage if desired (which likely also uses cookies).
Of course we only want these scripts loaded on pages where Umbraco Forms are present, but even checking if a value exists in TempData causes the Set-Cookie
header to be added.
It seems the goal is to share the form IDs being loaded so the scripts can be loaded elsewhere. Perhaps there are other uses I'm not aware of...
My question is: why has TempData
been chosen for this purpose? Could something like the HttpContext.Items
dictionary (which lives within the request) be used instead to avoid this unnecessary cookie? I believe this approach is also used by Smidge etc.
Simply changing away from TempData
would be a breaking change, but I see little harm in having both TempData
and HttpContext.Items
options available until a suitable time...
For now we have opted to add our entry into HttpContext.Items
whenever a form is rendered that we can check for in the layout.
This item has been added to our backlog AB#36435
I don't know the answer to the question I'm afraid... this was implemented before my time and it's just been carried over as is from version to version. Now you point it out though, it does seem like HttpContext.Items
would work just fine and would be a better option. We'll give it a try to see if it works as expected, and if so, I'm considering we could make it a configurable option to use TempData
or HttpContext.Items
for this tracking of forms rendered on the page for the purpose of rendering the appropriate scripts and form data.
That way you, or anyone else, can swap to use HttpContext.Items
, and we can make this the default from Forms 14.
This will be available in the next patch releases for Forms 12 and 13.
You'll be able to set the following in configuration:
"Umbraco": {
"Forms": {
"Options": {
"TrackRenderedFormsStorageMethod": "TempData|HttpContextItems"
},
TempData
will be the default but you can set to HttpContextItems
to use HttpContext.Items
instead. We'll likely make HttpContextItems
the default in Forms 14.
With that set you'll be able to render the scripts using:
if (Context.Items.TryGetValue("UmbracoForms", out object? formIdsObject) && formIdsObject is IEnumerable<Guid> formIds)
{
foreach (var formId in formIds)
{
@await Component.InvokeAsync("RenderFormScripts", new { formId, theme = "default" })
}
}
Or just use the tag helper which will use the appropriate storage method depending on configuration:
<umb-forms-render-scripts theme="default" />
That's awesome, thanks @AndyButland!