How to setup Sitecore Forms
Jamstack architecture assumes the back-end either does not exist or is limited to essential functions. With Uniform Deploy, the pages with Sitecore Forms are rendered successfully, but how does it submit the data if there is no Sitecore CD instance to accept the data? Moving from a server-side rendered approach to a static-site approach requires a change in.
tip
The Bejamas blog has a good description of the approach used to handle forms in a Jamstack site. It is not Sitecore-specific, but it contains useful information.
caution
This article covers steps for Sitecore Forms. The scenario with WFFM has not been tested.
#
Implementation options- Serve the pages with forms from the Sitecore CD server
- Pros: Simple to set up, forms submits and analytics are available in Sitecore, custom forms save action executed on Sitecore side
- Cons: Slower performance, reliance on Sitecore CD server to be up and running, which increases the cost and complexity of the infrastructure
- Proxy form submits to the Sitecore CD server
- Pros: Good performance for the content pages, relatively simple to set up, form submits available in Sitecore, custom forms save action executed on the Sitecore side
- Cons: Not secure enough, check the details below
- Migrate to non-Sitecore forms provider
- Pros: Fast and secure forms, many different options depending on the site needs, no need to have Sitecore CD up and running
- Cons: A little more complicated to set up than other examples, may require a learning curve for content editors to use the new UI
Examples of the non-Sitecore forms providers:
#
Proxying form submit to Sitecore origininfo
This solution is recommended for a development scenario.
Sitecore Forms use the AntiCSRF MVC feature. A dynamic token generated on each page request, which is then checked on the form submit. When the site is statically generated, the token is always the same. This prevents the AntiCSRF from working correctly. Because of this limitation, you must disable the AntiCSRF feature.
info
The following steps work on Uniform for Sitecore 4 and above.
#
Modify your applicationModify the /pages/[[...slug]].tsx
file like this:
import { ... HtmlPreProcessingInstruction,} from "@uniformdev/next";
const formInstruction: HtmlPreProcessingInstruction = { shouldPreprocessNode: (node: any) => { return ( node.name === "form" && node.attribs.action && node.attribs.action.startsWith("/formbuilder") ); }, preprocessNode: (node: any, children: any, index: number) => { node.attribs.action = "https://sitecore.server.hostname" + node.attribs.action },};
<UniformContextProvider ... htmlPreProcessingInstructions={[formInstruction]} > <PageComponent {...props}> ... </PageComponent></UniformContextProvider>
tip
Be sure to change the code above to use the host name for your Sitecore CD instance.
#
Disable AntiCSRFIf you do not disable AntiCSRF on the controller that handles form submits, the following error will occur when submitting a form from a static site: The required anti-forgery cookie "__RequestVerificationToken" is not present
In order to disable AntiCSRF, you must build a custom controller to handle form submits.
This involves copying the existing controller and removing the [ValidateFormRequest]
attribute from the method that handles the form submit.
Decompile
Sitecore.ExperienceForms.Mvc.Controllers.FormBuilderController
Remove the
[ValidateFormRequest]
attribute from theIndex
(post) method.Customize the
Sitecore.ExperienceForms.Mvc.Pipelines.Initialize.InitializeRoutes
processor:protected override void RegisterRoutes(RouteCollection routes, PipelineArgs args){ routes.MapRoute("FormBuilder", "formbuilder/{action}/{id}", new { controller = "FormBuilder", action = "Index", id = UrlParameter.Optional }, new[] { "Custom.Controllers" }); routes.MapRoute("FieldTracking", "fieldtracking/{action}", new { controller = "FieldTracking", action = "Register" });}
Add a Sitecore config patch file for the new controller:
<sitecore role:require="Standalone or ContentManagement or ContentDelivery"> <services> <register serviceType="Sitecore.ExperienceForms.Mvc.Controllers.FormBuilderController, Sitecore.ExperienceForms.Mvc" implementationType="Sitecore.ExperienceForms.Mvc.Controllers.FormBuilderController, Sitecore.ExperienceForms.Mvc" > <patch:attribute name="serviceType">Custom.Controllers.FormBuilderController, Custom.FormController</patch:attribute> <patch:attribute name="implementationType">Custom.Controllers.FormBuilderController, Custom.FormController</patch:attribute> </register> </services> <pipelines> <initialize> <processor type="Sitecore.ExperienceForms.Mvc.Pipelines.Initialize.InitializeRoutes, Sitecore.ExperienceForms.Mvc" > <patch:attribute name="type">Custom.InitializeFormRoutes, Custom.FormController</patch:attribute> </processor> </initialize> </pipelines></sitecore>
#
Migrate to a non-Sitecore forms providerThese steps will convert the MVC form rendering into a React rendering. Sitecore is no longer needed for handling forms. Jotform is used as an example, because it provides the features below:
- User-friendly forms editor
- Exporting reports into CSV, Excel, PDF
- Importing forms from an existing site, i.e. easier to convert a Sitecore form.
- It has a free tier for development purposes
Use this article to convert the
/sitecore/layout/Renderings/System/Forms/Mvc Form
component to React. Make sure to follow the steps to have the datasource available in the props.On your Uniform NodeJS site, install
react-jotform-embed
npm package:npm install react-jotform-embed --legacy-peer-deps
Replace the code in the MvcForm JS component with this:
import JotformEmbed from 'react-jotform-embed'; export const MvcForm = (props) => { const { renderingContext } = props; return <JotformEmbed src={renderingContext.datasource} />}
By default, React is disabled on Uniform kit sites. This is done for performance optimization. To enable, it modify tge
pages/_document.tsx
file:- import Document, { Html, Main, } from 'next/document'+ import Document, { Html, Main, NextScript, Head} from 'next/document' ... return ( <Html lang={fields._lang}> - <head>{uniformHead}</head> + <Head>{uniformHead}</Head> <body className="header-static"> <Main /> + <NextScript /> </body> </Html>
Register at https://www.jotform.com/, create a form, go to publish, and copy 'direct link to your form'. You may try importing a form from a public URL of any of your site form pages.
In the content item presentation details, set the form URL for the Mvc Form rendering datasource as text. This allows having different forms for different items.
tip
Using the
react-jotform-embed
npm package is optional. You may take regular iframe code from https://www.jotform.com/