HomeDev GuideRecipesAPI Reference
Dev GuideAPI ReferenceUser GuideLegal TermsGitHubNuGetDev CommunityOptimizely AcademySubmit a ticketLog In
Dev Guide

Content Delivery API and Forms

Describes the Optimizely Forms package for Optimizely Content Delivery API.

The ContentDeliveryApi.Forms – CD.Forms package supports form rendering in Single-Page Application (SPA) sites with Vue or React. A form template along with the required resources, such as jQuery, CSS, or external JavaScript, are returned by CD.Forms in JSON format, clients can use that information to render Optimizely Forms as in the standard Alloy site.

Install

The CD.Formsthe NuGet package installs package: EPiServer.ContentDeliveryApi.Forms. After installing the package, register the CD.Forms services by calling AddFormsApi():

public void ConfigureServices(IServiceCollection services) {
  services.AddFormsApi();
}

Then you need to register CD.Forms services in your IoC container:

public void ConfigureServices(IServiceCollection services) {
  ...
  services.AddFormsApi();
}

After that, the form data can now be acquired by making requests to endpoints in ContentDeliveryApi.Cms package, the same as for Page and Block.

Request – /api/episerver/v2.0/content/85

Response:

1497

As illustrated by the image, form data is stored in property formModelin JSON result returned. This property contains two pieces of main information:

  • template – The HTML form template.
  • assets – Contains the required resources  (JavaScript and CSS) for Optimizely Forms.

FormRenderingService.js

This class is a kind of library that helps you render forms in your JavaScript framework with the form template and required resources. It is stored under the folder /Scripts/. This service works in the following order:

  1. Attach the form HTML template to an attach point.
  2. Inject the form's CSS.
  3. Execute the form's script in the correct order.

A note here is that two arguments are required:

  • formModel – Data returned from Content Delivery API.
  • element – A DOM node or (node ID) attached to the form template.

A form's hosted page

In a standard Alloy site, the FormContainerBlockController can resolve the form's hosted page link from the requested URL. However, on a SPA site, you interact with FormContainerBlockController from the Content Delivery API, so the request context is missed. This causes the form to resolve the hosted page incorrectly and leads to errors such as wrong SubmittedFrom data and form steps are not displayed because the page is incorrect.

To solve this problem, Content Delivery API checks for a request parameter named currentPageUrl and use it to resolve the current page. When requesting the form model from the Content Delivery API, the client should include this parameter with the value pointing to the current URL.

const parameters = {
  expand         : '*',
  currentPageUrl : window.location.pathname
};

Music Festival and CD.Forms

The Music Festival template site demonstrates how to use Content Delivery API to render a form in a SPA site. Music Festival is written in Vue.js, but it is the same if your SPA uses React, Angular, or something else.

📘

Note

This is an example only to demonstrate how you can work with CD.Forms. You can check out the Music Festival code on GitHub.

To make Music Festival work with Optimizely Forms, check out the latest code and make some modifications.

FormContainerBlock.vue

First, you need a Vue component that is responsible for handling form blocks. Create a container node in this component so the form template can be attached.

<template>
  <div class="FormContainerBlock">
    <div :id="'formContainer_' + model.contentLink.id"></div>        
  </div>
</template>

Then, on the event mounted, use the FormRenderingService.js to render the form based on the formModel property.

import EpiProperty from '@/Scripts/components/EpiProperty.vue';
import ContentArea from '@/Scripts/components/ContentArea.vue';
import formRenderingService from '@/Scripts/formRenderingService';

export default 
  {
    props: ['model'],
    methods: 
      {
        renderForm: function () 
          {
            var element = document.getElementById('formContainer_' + this.model.contentLink.id);
            formRenderingService.render(this.model.formModel, element);
          }
      },
    components: 
      {
        EpiProperty,
        ContentArea
      },
    mounted() 
      {
        this.renderForm();
      },
    updated: function () 
      {
        this.renderForm();
      }
  };

Lastly, register the component to the Vue engine (in main.js):

import FormContainerBlock from '@/Scripts/components/blocks/FormContainerBlock.vue';
Vue.component('FormContainerBlock', FormContainerBlock);

Edit api.js

By default, Music Festival uses friendly URLs to acquire content from Content Delivery API and does not send an Accept-Language header. However, in the case of forms, send the language header to retrieve the correct version if your forms have multiple languages.

getContentByContentLink: (contentLink, parameters, headers) => 
  {
    if (headers == null) {headers = { 'Accept-Language': '' };}
    return get(`${applicationPath}api/episerver/v2.0/`, `content/${contentLink}`, parameters, headers);
  }

Add currentPageUrl parameter in epiDataModel.js

Modify epiDataModel.js so it includes an extra currentPageUrl parameter when sending a request to retrieve content.

const parameters = {
  expand         : '*',
  currentPageUrl : window.location.pathname
};

Rebuild client resources

Rebuild the client resources of the Music Festival site for the changes to take effect. Open a command line at the project's root folder and type npm run build to run the build script.

After the build process finishes, create a form in edit view, drag it, and drop it on any page, and it will display automatically.

📘

Note

Music Festival’s on-page edit view does not support Optimizely Forms currently, so use the all properties view to create and edit a form.

1202

Edit Form in All Properties view.

1511

Drag a form to page content area.

1416

The form should automatically be displayed in view mode.