Render Sitecore Experience Forms Using Sitecore XP 10.4 with a Headless Approach (Next.js + JSS SDK)

 


In this blog post, we’ll walk through rendering Sitecore Experience Forms using Sitecore XP 10.4 (Update 1) with a headless (Sitecore-first) approach, leveraging Next.js and Sitecore JSS SDK. This guide assumes you're using connected mode, where your frontend directly interacts with your Sitecore backend.

Goal: Enable a fully functional Sitecore Experience Form to render and work within a headless Next.js application.


🧱 Prerequisites

Before getting started, ensure you have the following:

Backend:

  • ✅ Sitecore XP 10.4 Update-1 installed

  • ✅ Sitecore Headless Rendering 22.0.0 package installed

Frontend:

  • ✅ Node.js and npm installed

  • ✅ Visual Studio Code (or any preferred IDE)


🧭 Step 1: Set Up Sitecore for Headless Forms

Since this is a Sitecore-first approach, we begin by configuring everything in Sitecore before moving to Next.js.


🔑 1. Create an API Key

  • Go to Sitecore Content Editor

  • Create a new API Key item (e.g., under /sitecore/system/Modules/Layout Service/API Keys)

  • Note down the Item ID — this will be your API Key used in the frontend.




🧱 2. Create a JSON Layout

  • Create a Layout item using the appropriate JSON rendering template.

  • This layout will be responsible for exposing your page and component structure via the Layout Service.




📌 3. Add a Placeholder (jss-main)

  • Add a placeholder called jss-main to the layout.

  • In the Allowed Controls field, define which components can be rendered inside it (e.g., your custom form component).




🧩 4. Create a Form Component Rendering

  • Add a new rendering item for your form component.

  • Important:

    • Set Rendering Contents Resolver to Sitecore Forms Resolver.

    • Ensure the Component Name exactly matches the name you’ll use in the Next.js component (e.g., Quizform).







📐 5. Link Placeholder to Layout Service

  • Revisit your layout item.

  • Under Layout Service Placeholders, add the jss-main placeholder.




📋 6. Create the Experience Form

  • Go to Forms in the Sitecore dashboard.

  • Create a new form (e.g., “Quiz Form”) — this will serve as the data source.




📄 7. Configure the Page Item

  • Go to the page item where you want to render the form.

  • Assign the layout you created.

  • Insert the form component and link it to the form data source.







🌐 8. Set Up a Plain HTTP Binding in IIS

To avoid SSL and CORS issues when using self-signed certificates:

  • Create a new IIS binding for your Sitecore site using HTTP.

  • Add the host entry to your hosts file (e.g., 127.0.0.1 mysitecore.local).




💻 Step 2: Create the Next.js Frontend App

With Sitecore set up, now let’s create and configure your frontend using Next.js and Sitecore JSS.


🏗️ 1. Generate the Next.js JSS App

In your terminal:


npm install -g @sitecore-jss/sitecore-jss-cli npx create-sitecore-jss

  • Select Next.js with SSR

  • When prompted:

    • Enter the Sitecore host with HTTP (e.g., http://mysitecore.local)







npm install @sitecore-jss/sitecore-jss-forms @sitecore-jss/sitecore-jss-react-forms


npm run build


⚙️ 2. Set Up the App

Run:


jss setup
  • Provide your Sitecore host and API key 




📦 3. Deploy Configuration



jss deploy config
  • This deploys config files like component definitions to Sitecore.







🛠️ 4. Scaffold the Form Component


jss scaffold Quizform



This creates a new React component. Replace the generated content with the following Sitecore-recommended code:


import { Form } from '@sitecore-jss/sitecore-jss-react-forms'; import React, { useState, useEffect } from 'react'; import { NextRouter, withRouter } from 'next/router'; import { sitecoreApiKey } from 'temp/config'; const Quizform = ({ fields, router }: { fields: any; router: NextRouter }) => { const [formData, setFormData] = useState(fields); const [formVersion, setFormVersion] = useState(0); useEffect(() => { setFormData(fields); setFormVersion((v) => v + 1); }, [fields]); useEffect(() => { const originalFetch = window.fetch; window.fetch = async (...args) => { const response = await originalFetch(...args); if ( args[0]?.toString().includes('api/jss/formbuilder') && response.headers.get('content-type')?.includes('application/json') ) { const json = await response.clone().json(); if (json?.redirectUrl) delete json.redirectUrl; if (json?.nextForm) { setFormData(json.nextForm); setFormVersion((v) => v + 1); } return new Response(JSON.stringify(json), { status: response.status, headers: { 'Content-Type': 'application/json' } }); } return response; }; return () => { window.fetch = originalFetch; }; }, []); if (!formData) return null; return ( <Form key={formVersion} language={router.locale} form={formData} sitecoreApiHost={''} sitecoreApiKey={sitecoreApiKey} onRedirect={() => console.log('Redirect prevented')} /> ); }; export default withRouter(Quizform);

🌍 5. Update .env and scjssconfig.json

Update your environment variables 

  • JSS_EDITING_SECRET(Update the JSS_EDITING_SECRET key in the .env file with the value of the deploySecret key from the scjssconfig.json file.)

  • SITECORE_API_KEY(As per your environment item of the api key created in sitecore instance in previous setsp)

  • SITECORE_SITE_NAME( this value you can fetch from the name attribute of the site tag present inside jss-quix-demo.config file  folder of the next js project)

  • GRAPH_QL_ENDPOINT(/sitecore/api/graph/edge)

  • SITECORE_API_HOST(Sitecore host name HTTP version ,the new binding created in IIS)









🔄 6. Modify next.config.js

Update rewrites to route API calls to Sitecore:


{ source: '/api/jss/:path*', destination: `${jssConfig.sitecoreApiHost}/api/jss/:path*`, }



🔄 7. Modify layout.tsx file

 Update the tag as described below:

By default, it uses the PageTitle field. If your page item does not have this field, it will throw an error.


To resolve this:


Update the field name in the interface defined in this layout.


Use the same field name in the title tag.

<title>{fields.pageTitle.value.toString() || 'Page'}</title>






🚀 Step 3: Run the App in Connected Mode

Start the project:


npm run start:connected

Then visit:
📍 http://localhost:3000




You should see your Sitecore Experience Form rendered on the page, fully functional. On submission, the form data will be stored in the Sitecore database — just like it would in a traditional Sitecore-rendered site.





✅ Conclusion

Congratulations! You've successfully rendered a Sitecore Experience Form in a headless Next.js app using Sitecore-first configuration.

🔁 Recap:

StepTask
1Configure Sitecore (layouts, placeholders, form component)
2Scaffold the frontend with JSS CLI
3Deploy config and set up the form component
4Run in connected mode and test form submission

💡 You now have a flexible, scalable setup that can leverage Sitecore forms with modern headless frontend capabilities.

Comments

Popular posts from this blog

Solrcloud With Zookeeper -Single server setup

Next.js with XM Cloud EDGE and GraphQL