Skip to main content
Skip table of contents

VA Forms Library - Form Config Options

Last Updated: March 27, 2025

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.

These form configuration options add the settings for your form/application. These options include the main form/application ID, title, subtitle, root URL, dependencies, components, chapters, page order and how data is processed for prefill and submission.

Here is a list of available form configuration options:

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 or function

The subtitle of the form, usually the form number. The subtitle is rendered on all pages when there's also a title. Accepts a string or function; params include (currentLocation, formConfig, formData, children).

subTitle: 'VA Form 10182 (Notice of Disagreement)' or subTitle: ({ formData }) => formData.changeSubTitle ? 'Form 345 with Form 123' : 'Form 123'

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 11 migrations functions in the 21-526EZ Form. The version of this form is '11'.

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 }) => {}

onFormExit

function

Overall form function called when the user clicks on the "Finish this application later" link. This function has the form data passed in as an argument, and the data (altered or unaltered) must be returned. Note this overall function is called after the page onFormExist function

onFormExit: formData => { window.sessionStorage.removeItem('foo'); return formData; },

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'

useCustomScrollAndFocus

boolean

Enables custom page focus. Default page focus will switch to the first H3 (inside of the #main div), which should be unique, on the page. If the H3 doesn't exist, it'll fall back to the first H2, which contains the “Step x of y” text.

useCustomScrollAndFocus: true

scrollAndFocusTarget

string or function

This sets a global custom scroll and focus target function for all pages. It can be overridden by defining a scrollAndFocusTarget for a specific page. Both the page scroll and the focus target needs to be handled in the function. The function includes one parameter, the page index, if the page is within an array (when using showPagePerItem).

scrollAndFocusTarget: 'h3'

or

JS
scrollAndFocusTarget: index => {
  const h3Alert = document.querySelector('va-alert[status="error"] h3');
  const h3 = document.querySelector('h3');
  if (h3Alert) {
    scrollAndFocus(h3Alert);
  } else if (h3) {
    scrollAndFocus(h3);
  } else {
    scrollToTop();
    focusElement('h1');
  }

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-0994 Education Benefits Form:

JS
savedFormMessages: {
    notFound: 'Please start over to apply for education benefits.',
    noAuth:
      'Please sign in again to resume your application for education benefits.',
  },

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 21-527EZ pension benefits form:

JS
<SaveInProgressIntro
  prefillEnabled={formConfig.prefillEnabled}
  pageList={pageList}
  downtime={route.formConfig.downtime}
  startText="Start the pension application"
  retentionPeriod="one year"
  retentionPeriodStart="when you start"
  continueMsg={<FormReactivationAlert />}
/>

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:

JS
 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
  },

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:

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

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:

JS
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',
  }

From the COE (Certificate of Eligibility) Form:

JS
customText: {
  appAction: 'your COE request',
  appSavedSuccessfullyMessage: 'Your request has been saved.',
  appType: 'request',
  continueAppButtonText: 'Continue your request',
  finishAppLaterMessage: 'Finish this request later',
  startNewAppButtonText: 'Start a new request',
  reviewPageTitle: 'Review your request',
},

preSubmitInfo

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

Properties

Value Type

Example

required

boolean

required: false or required: true

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'

statementOfTruth

object

statementOfTruth: {} This enables the Statement of Truth functionality. Further customizations can be made by using the below properties nested inside this object. For default values, consult the preSubmitInfo file linked above.

heading

string

CODE
statementOfTruth: {
  heading: "Veteran's Statement of Truth"
}

body

string

CODE
statementOfTruth: {
  body: 'I certify that I am applying for assistance.'
}

messageAriaDescribedby

string

CODE
statementOfTruth: {
  messageAriaDescribedby: 'I certify that I am applying for assistance.'
}

Usually, this should be the same as body

textInputLabel

string

CODE
statementOfTruth: {
  textInputLabel: "Veteran's full name"
}

checkboxLabel

string

CODE
statementOfTruth: {
  checkboxLabel: 'I certify the information above is correct'
}

fullNamePath

string

CODE
statementOfTruth: {
  fullNamePath: 'applicant.fullName'
}

preSubmitInfo examples

From the 22-0994 Education Benefits Form:

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

From the Platform’s default value:

JS
preSubmitInfo: {
  required: true,
  notice: (
    <div className="vads-u-margin-y--2">
      <strong>Note:</strong> According to federal law, there are criminal
      penalties, including a fine and/or imprisonment for up to 5 years, for
      withholding information or for providing incorrect information. (See 18
      U.S.C. 1001)
    </div>
  ),
  field: 'privacyAgreementAccepted',
  label: (
    <span>
      I have read and accept the{' '}
      <a
        aria-label="Privacy policy, will open in new tab"
        target="_blank"
        href="/privacy-policy/"
      >
        privacy policy
      </a>
    </span>
  ),
  error: 'You must accept the privacy policy before continuing.',
}

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:

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

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'

hideFormNavProgress (optional)

boolean

hideFormNavProgress: true

pages

object

reviewDescription

object

reviewDescription: ReviewDescription

depends

boolean

depends: formData => hasSecondaryCaregiverTwo(formData)

chapters example

From the 21-526EZ Disability Claim Form:

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

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

Function called when the user clicks on the form "Continue" navigation button. Form data may be altered, but navigation will not be blocked

onContinue: (formData, setFormData) => { setFormData({ ...formData, 'view:test': false }); },

onFormExit

function

Specific page function called when the user clicks on the "Finish this application later" link. This function has the form data passed in as an argument, and the data (altered or unaltered) must be returned. Note this specific page function is called before the overall form onFormExist function

onFormExit: formData => { window.sessionStorage.removeItem('foo'); return formData; },

pageClass

string

Class for page stylesheet.

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

returnUrl

string

Add a return url path (include leading /) for a page that is usually hidden and should not be accessible using the form navigation (back and continue) buttons. This prevents the autosave from saving a path to a page in the middle of a list loop

returnUrl: '/dependent-summary'

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 are rendered on the review & submit page

editModeOnReviewPage: true

scrollAndFocusTarget

string or function

This set the custom scroll and focus targets for a specific page. Set this as a string to target a specific element, or use a function if the target changes based on certain conditions, e.g. focus on a checkbox. Both the page scroll and the focus target needs to be handled in the function. The function includes one parameter, the page index, if the page is within an array (when using showPagePerItem).

scrollAndFocusTarget: 'va-alert'

or

JS
scrollAndFocusTarget: index => {
  scrollToTop();
  // using checkbox web component
  const checkbox = document.querySelector('va-checkbox');
  focusElement('input', {/* focus options */}, checkbox.shadowRoot);
}

pages example

From the Education Benefits FEEDBACK-TOOL Form:

JS
      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: {...
          },
        },
      },

Putting it together

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

JS
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;

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.