To create the form/application using the Forms Library, we need to set up the form's configuration. The application code uses the Form Config to determine which React components to render to build the form. We can also customize the form through this configuration.

Here is a list of form configuration options available.

Options

Value Type

Description

Example

rootUrl

string

Application directory.

rootUrl: manifest.rootUrl

urlPrefix

string

Prefix string to add to the path for each page.

urlPrefix: '/'

introduction

component

The introduction page component. To exclude an introduction page, remove this component.

introduction: IntroductionPage

confirmation

component

The confirmation page component that will render after the user successfully submits the form.

confirmation: ConfirmationPage

trackingPrefix

string

The prefix for Google Analytics events that are sent for different form actions.

trackingPrefix: '10182-board-appeal-'

title

string or function

The title of the form, rendered on all pages. Accepts a string or function; params include (currentLocation, formConfig, formData, children).

title: 'Request a Board Appeal'

or

title: ({ formData }) => formData.needsNewTitle ? 'Alternate' : 'Form'

subTitle

string

The subtitle of the form, usually the form number. The subtitle is rendered on all pages when there's also a title.

subTitle: 'VA Form 10182 (Notice of Disagreement)'

defaultDefinitions

object

Schema definitions that can be referenced on any page. These are added to each page's schema in the reducer code, so that you don't have to put all of the common fields in the definitions property in each page schema. For more information on definitions, see the VA Forms Library - About schema and uiSchema page.

defaultDefinitions: {}

prefillTransformer

function

When a user begins completing a pre-filled form, this function is called after data migrations are run for pre-filled data to make necessary updates to the data or form schema ahead of time.

prefillTransformer: (pages, formData, metadata ) => { pages, formData, metadata }

migrations

array

An array of functions that are applied during a form's lifecycle. The number of migration functions should be equal to the version.

For example, there are two migration functions in 21P-530 Form. The version of this form is '2.'

migrations: [urlMigration('/10203')]

version

number

Indicates the version of a form, this should be increased by one when a migration is required.

version: 0

submitUrl

string

Path to vets-api controller for form submission.

submitUrl: `${environment.API_URL}/v0/health_care_applications`

submit

function

Function that’s called upon form submission.

Optional: If a custom submit isn’t provided, there’s a system default that runs.

submit: (form, formConfig) => {}

transformForSubmit

function

Called during form submission to transform submitted schema data (Optional).

Calling transformForSubmit in platform/forms-system/src/js/helpers will remove view fields from the schema data. 

transformForSubmit: (formConfig, form) => {}

errorText

component

Component used as part of the default error message if submission of the form fails.

errorText: ErrorText

submissionError

function

Component that replaces the default error message component if submission of the form fails.

submissionError: ({ form }) => {}

savedFormMessages

object

See the savedFormMessages section.

wizardStorageKey

string

Defaults to WIZARD_STATUS in 'platform/site-wide/wizard'. Added here if your form uses a unique sessionStorage key (currently only used by the save-in-progress component).

wizardStorageKey: 'wizardStatus'

saveInProgress

object

Contains the Save in Progress (SiP) configuration.

See the saveInProgress section.

prefillEnabled

boolean

Enables prefill.

prefillEnabled: false

downtime

object

See the downtime section.

verifyRequiredPrefill

boolean

Verify the required pre-filled information is available to show on the form.

verifyRequiredPrefill: false

preSubmitInfo

object

Additional information to be displayed on the Review page.

See platform/forms/preSubmitInfo for the standard object.

preSubmitInfo: {}

footerContent

component

Content to be displayed at bottom of a form, see platform/forms/components/FormFooter for the standard object.

footerContent: FormFooter

getHelp

component

Component that’s displayed as part of standard footerContent property.

getHelp: GetHelpComponent

onFormLoaded

function

Function called during the loading of a form.

onFormLoaded: ({formData, savedForms, returnUrl, formConfig, router }) => {}

formSavedPage

component

Component displayed when a form has been saved.

If not provided, platform/forms/save-in-progress/FormSaved.jsx is used instead.

formSavedPage: FormSaved

additionalRoutes

array

Provides additional routes that are not found within the page lists.

Introduction and review-and-submit pages are added in automatically.

customText

object

Custom text values that will be used throughout a form.

chapters

object

The object that contains the configuration for each chapter.

intentToFileUrl

string

Deprecated properties still in use in applications/disability-benefits/all-claims/config/form.js.

intentToFileUrl: '/evss_claims/intent_to_file/compensation'

submitErrorText

component

Deprecated properties still in use in applications/hca/config/form.js.

submitErrorText: ErrorMessage

showReviewErrors

boolean

Show error links on the review page.

showReviewErrors: !environment.isProduction()

ariaDescribedBySubmit

string

This identifies the element that describes the element on which the attribute is set.

ariaDescribedBySubmit: '22-0994-submit-application'

savedFormMessages

Messages to be sent to the Save-in-Progress (SiP) component. 

Properties

Value Type

Example

notFound

string

notFound: 'You can’t reorder your items at this time because your items aren’t available for reorder or we can’t find your records in our system. For help, please call the Denver Logistics Center (DLC) at 303-273-6200 or email us at dalc.css@va.gov.'

noAuth

string

noAuth: 'Please sign in again to continue your application for benefits.'

forbidden

string

forbidden: 'We can’t fulfill an order for this Veteran because they are deceased in our records. If this information is incorrect, please call Veterans Benefits Assistance at 800-827-1000, Monday through Friday, 8:00 a.m. to 9:00 p.m. ET.'

savedFormMessages examples

From the 22-0993 Education Benefits Form:

savedFormMessages: {
    notFound:
      'Please start over to apply to opt out of sharing VA education benefits information.',
    noAuth:
      'Please sign in again to continue your application to opt out of sharing VA education benefits information.',
  },
JS

savedFormMessages is typically passed into a SaveInProgressIntro component in the form's introduction container. In the example below, this is passed into the property "messages".

From the COVID-VACCINE-TRIAL Introduction page:

<SaveInProgressIntro
    prefillEnabled={this.props.route.formConfig.prefillEnabled}
    messages={this.props.route.formConfig.savedFormMessages}
    pageList={this.props.route.pageList}
    startText="Volunteer for COVID-19 research"
>
    Please complete the 12345 form to apply for vaccine trial
    participation.
</SaveInProgressIntro>
JS

saveInProgress

This is the configuration for setting the status messages, callback, and resume form.

Properties

Value Type

Description

messages

object

These messages will be displayed as-is when appropriate.

restartFormCallback

function

Form restart-specific options.

This callback is only called by the RoutedSavableApp, so if the wizard is being rendered by the outer form App file, this callback won't work. If the wizard is being rendered within the Intro page (like 0996 HLR), then have the function return a destination route ('/' is the introduction page).

resumeOnly

boolean

The configuration for hiding the "start a new app" button on the form saved page. Users cannot restart a form once started.

messages

This is the message object of saveInProgress. It contains the status of the saved information on the form.

Properties

Value Type

Example

inProgress

string

inProgress:'Your education benefits application (22-1995) is in progress.',

expired

string

expired:'Your saved education benefits application (22-1995) has expired. If you want to apply for education benefits, please start a new application.'

saved

string

saved: 'Your education benefits application has been saved.'

saveInProgress example

From the 20-0996 Disability Benefits Form:

 saveInProgress: {
    messages: {
      inProgress:
        'Your Higher-Level Review application (20-0996) is in progress.',
      expired:
        'Your saved Higher-Level Review application (20-0996) has expired. If you want to apply for Higher-Level Review, please start a new application.',
      saved: 'Your Higher-Level Review application has been saved.',
    },
    // return restart destination url
    restartFormCallback: () => '/', // introduction page
  },
JS

downtime

A list of services that correspond to those for which there is downtime information provided by the API. The full list of services can be found in platform/monitoring/DowntimeNotification/config.

Properties

Value Type

Example

requiredForPrefill

boolean

requiredForPrefill: true

dependencies

array

dependencies: [services.evss, services.emis, services.mvi, services.vet360]

message

string

message: DowntimeMessage

downtime example

From the 10182 Appeals Form:

downtime: {
    requiredForPrefill: true,
    dependencies: [
      services.vaProfile,
      services.bgs
      services.mvi,
      services.appeals,
    ],
  },
JS

customText

Custom text values that will be used throughout a form.

Properties

Value Type

Example

reviewPageTitle

string

reviewPageTitle: 'Review order details'

appSavedSuccessfullyMessage

string

appSavedSuccessfullyMessage: 'Order has been saved.'

startNewAppButtonText

string

startNewAppButtonText: 'Start a new order'

continueAppButtonText

string

continueAppButtonText: 'Continue your order'

finishAppLaterMessage

string

finishAppLaterMessage: 'Finish this order later.'

appType

string

appType: 'order'

appAction

string

appAction: 'placing your order'

submitButtonText

string

submitButtonText: 'Submit your request'

appContinuing

string

appContinuing: 'for disability compensation'

customText examples

From the MDOT Form:

customText: {
    reviewPageTitle: 'Review order details',
    appSavedSuccessfullyMessage: 'Order has been saved.',
    startNewAppButtonText: 'Start a new order',
    continueAppButtonText: 'Continue your order',
    finishAppLaterMessage: 'Finish this order later.',
    appType: 'order',
    appAction: 'placing your order',
  }
JS

From the HC-QSTNR (Health Care Questionnaire) Form:

customText: {
    reviewPageTitle: 'Review',
    appType: 'questionnaire',
    appAction: 'answering questions',
    continueAppButtonText: 'Continue questions',
    finishAppLaterMessage: 'Finish this questionnaire later.',
    appSavedSuccessfullyMessage: 'Questionnaire has been saved.',
    submitButtonText: 'Submit answers',
  }
JS

preSubmitInfo

Additional information to be displayed on the Review page. See platform/forms/preSubmitInfo for the standard object.

Properties

Value Type

Example

required

boolean

path: 'additional-route'

field

string

field: 'privacyAgreementAccepted'

notice

string

notice: '<div>Notice</div>'

label

string

label: 'I accept the privacy agreement'

error

string

label: 'I accept the privacy agreement'

CustomComponent

component

error: 'You must accept the privacy agreement'

preSubmitInfo examples

From the 22-0994 Education Benefits Form:

 preSubmitInfo: {
    CustomComponent: PreSubmitInfo,
    required: true,
    field: 'privacyAgreementAccepted',
  },
JS

From the COVID-VACCINE-TRIAL Form:

preSubmitInfo: {
    required: true,
    field: 'consentAgreementAccepted',
    label: ConsentLabel(),
    notice: ConsentNotice(),
    error: ConsentError(),
  },
JS

additionalRoutes

Provides additional routes that are not found within the page lists. It contains array of additional route objects.

Properties

Value Type

Example

path

string

path: 'additional-route'

component

string

component: AdditionalComponent

pageKey

string

pageKey: 'additional-route'

depends

function

depends: () => {}

additionalRoutes example

From the 1010ez Form:

additionalRoutes: [
    {
      path: 'id-form',
      component: IDPage,
      pageKey: 'id-form',
      depends: () => !hasSession(),
    },
],
JS

chapters

The object that contains the configuration for each chapter. Each property is the key for a chapter.

Properties

Value Type

Example

title

string or function

title: 'Veteran details'

pages

object

reviewDescription

object

reviewDescription: ReviewDescription

depends

boolean

depends: formData => hasSecondaryCaregiverTwo(formData)

chapters example

From the 21-526EZ Disability Claim Form:

  chapters: {
    veteranDetails: {
      title: isReviewPage => `${isReviewPage ? 'Review ' : ''}Veteran Details`,
      pages: {...
    },
    disabilities: {
      title: 'Disabilities', 
      pages: {...
    },
    supportingEvidence: {...
    },
    additionalInformation: {
      title: 'Additional information',
      pages: {...
    },
  },
JS

pages

The object that contains the pages in each chapter.  Each property is the key for a page, and should be unique across chapters.

Properties

Value Type

Description

Example

path

string

The URL for the page.

path: 'applicant-relationship'

title

string or function

The title of the page that renders on the review page. ‘title’ can also be a function that receives the current data as a parameter.

title: 'Veteran details'

initialData

object

Any initial data that should be set for the form.

initialData: {}

showPagePerItem

boolean

Specifies that a page will turn its schema into a page for each item in an array, such as an array of children with a page for each child. The schema/uiSchema for this type of page should be built as usual for an array field.

showPagePerItem: true

depends

boolean

A dependency needed to show the page.

depends: formData => !isTypeNone(formData)

arrayPath

string

The path to the array.

arrayPath: 'arrayProp'

itemFilter

boolean

Items in the array that should not have a page.

itemFilter: item => !isDisabilityPtsd(item.condition)

hideHeaderRow

boolean

Hide header row.

hideHeaderRow: true

CustomPage

component

The custom page component will be rendered instead of using uiSchema.

CustomPage: EditPhone

CustomPageReview

component

The custom review page component will be rendered instead of using uiSchema.

CustomPageReview: EditPhone

onContinue

function

Capture the event when the user clicks "Continue" on the form.

onContinue: captureEvents.benefitsEligibility

pageClass

string

Class for page stylesheet.

pageClass: 'vads-u-max-width--100 vads-u-vads-u-width--full'

subTitle

string

Subtitle for the form.

subTitle: formSubTitle

schema

object

The JSON schema object for the page, following the JSON Schema format.

uiSchema

object

The JSON schema object for the user interface on the page, following the JSON Schema format.

editModeOnReviewPage

boolean

Controls which fields & widgets are rendered on the review & submit page

editModeOnReviewPage: true

pages example

From the Education Benefits FEEDBACK-TOOL Form:

      pages: {
        applicantRelationship: {
          path: 'applicant-relationship',
          title: 'Applicant Relationship',
          uiSchema: {...
          },
          schema: {...
          },
        },
        applicantInformation: {
          path: 'applicant-information',
          title: 'Applicant Information',
          depends: isNotAnonymous,
          uiSchema: {...
          },
          schema: {...
          },
        },
        serviceInformation: {
          path: 'service-information',
          title: 'Service Information',
          depends: isVeteranOrServiceMember,
          uiSchema: {...
          },
          schema: {...
          },
        },
        contactInformation: {
          path: 'contact-information',
          title: 'Contact Information',
          depends: formData => formData.onBehalfOf !== anonymous,
          uiSchema: {...
          },
          schema: {...
          },
        },
      },
JS

Putting it together

This is a complete formConfig example from the 10182 Appeals Form:

const formConfig = {
  rootUrl: manifest.rootUrl,
  urlPrefix: '/',
  submitUrl: `${environment.API_URL}/v0/notice_of_disagreements`,
  trackingPrefix: '10182-board-appeal-',

  downtime: {
    requiredForPrefill: true,
    dependencies: [
      services.vaProfile,
      services.bgs,
      services.mvi,
      services.appeals,
    ],
  },

  formId: VA_FORM_IDS.FORM_10182,
  version: migrations.length - 1,
  title: 'Request a Board Appeal',
  subTitle: 'VA Form 10182 (Notice of Disagreement)',

  prefillEnabled: true,
  prefillTransformer,
  verifyRequiredPrefill: true,
  transformForSubmit: transform,
  preSubmitInfo,
  submit: submitForm,

  // SaveInProgress messages
  customText,
  savedFormMessages,
  saveInProgress,
  // errorText: '',
  // submissionError: '',

  introduction: IntroductionPage,
  confirmation: ConfirmationPage,

  defaultDefinitions: {},
  chapters: {
    infoPages: {
      title: 'Veteran details',
      reviewDescription: ReviewDescription,
      pages: {
        veteranInformation: {
          title: 'Veteran details',
          path: 'veteran-details',
          uiSchema: veteranInfo.uiSchema,
          schema: veteranInfo.schema,
          // initialData,
        },
        homeless: {
          title: 'Homelessness question',
          path: 'homeless',
          uiSchema: homeless.uiSchema,
          schema: homeless.schema,
        },
        contactInformation: {
          title: 'Contact information',
          path: 'contact-information',
          uiSchema: contactInfo.uiSchema,
          schema: contactInfo.schema,
        },
      },
    },
    conditions: {
      title: 'Issues for review',
      pages: {
        contestableIssues: {
          title: 'Issues eligible for review',
          path: 'eligible-issues',
          uiSchema: contestableIssues.uiSchema,
          schema: contestableIssues.schema,
        },
        additionalIssuesIntro: {
          title: 'Additional issues for review',
          path: 'additional-issues-intro',
          depends: showAddIssueQuestion,
          uiSchema: additionalIssuesIntro.uiSchema,
          schema: additionalIssuesIntro.schema,
          appStateSelector,
        },
        additionalIssues: {
          title: 'Add issues for review',
          path: 'additional-issues',
          depends: showAddIssuesPage,
          uiSchema: additionalIssues.uiSchema,
          schema: additionalIssues.schema,
          appStateSelector,
        },
        areaOfDisagreementFollowUp: {
          title: getIssueName,
          path: 'area-of-disagreement/:index',
          showPagePerItem: true,
          arrayPath: 'areaOfDisagreement',
          uiSchema: areaOfDisagreementFollowUp.uiSchema,
          schema: areaOfDisagreementFollowUp.schema,
        },
        optIn: {
          title: 'Opt in',
          path: 'opt-in',
          uiSchema: optIn.uiSchema,
          schema: optIn.schema,
        },
        issueSummary: {
          title: 'Issue summary',
          path: 'issue-summary',
          uiSchema: issueSummary.uiSchema,
          schema: issueSummary.schema,
        },
      },
    },
    boardReview: {
      title: 'Board review option',
      pages: {
        boardReviewOption: {
          title: 'Board review option',
          path: 'board-review-option',
          uiSchema: boardReview.uiSchema,
          schema: boardReview.schema,
        },
        evidenceIntro: {
          title: 'Evidence submission',
          path: 'evidence-submission',
          depends: canUploadEvidence,
          uiSchema: evidenceIntro.uiSchema,
          schema: evidenceIntro.schema,
        },
        evidenceUpload: {
          title: 'Evidence upload',
          path: 'evidence-submission/upload',
          depends: wantsToUploadEvidence,
          uiSchema: evidenceUpload.uiSchema,
          schema: evidenceUpload.schema,
        },
        hearingType: {
          title: 'Hearing type',
          path: 'hearing-type',
          depends: needsHearingType,
          uiSchema: hearingType.uiSchema,
          schema: hearingType.schema,
        },
      },
    },
  },
  footerContent: FormFooter,
  getHelp: GetFormHelp,
};

export default formConfig;
JS