Skip to content

Latest commit

 

History

History
178 lines (132 loc) · 8.31 KB

File metadata and controls

178 lines (132 loc) · 8.31 KB

Getting started with DXT

  1. Foundational knowledge
  2. Add forms-engine-plugin as a dependency
  3. Register DXT as a hapi plugin
  4. Handling static assets
  5. Environment variables
  6. Creating and loading a form

Foundational knowledge

DXT's forms engine is a plugin for a frontend service, which allows development teams to construct forms using configuration and minimal code. Forms are closely based on the knowledge, components and patterns from the GDS Design System. Forms should remain as lightweight as possible, with business logic being implemented in a backend/BFF API and DXT used as a simple presentation layer.

You should aim, wherever possible, to utilise the existing behaviours of DXT. Our team puts a lot of effort into development, user testing and accessibility testing to ensure the forms created with DXT will be of a consistently high quality. Where your team introduces custom behaviour, such as custom components or custom pages, this work will now need to be done by your team. Where possible, favour fixing something upstream in the plugin so many teams can benefit from the work we do. Then, if you still need custom behaviour - go for it! DXT is designed to be extended, just be wise with how you spend your efforts.

When developing with DXT, you should favour development using the below priority order. This will ensure your team is writing the minimum amount of code, focusing your efforts on custom code where the requirements are niche and there is value.

  1. Use out-of-the box DXT components and page types (components, controllers)
  2. Use configuration-driven advanced functionality to integrate with backends and dynamically change page content (page events, page templates)
  3. Use custom views, custom components and page controllers to implement highly tailored and niche logic (custom Nunjucks, custom Javascript)

Contributing back to DXT

When you build custom components and page controllers, they might be useful for other teams in Defra to utilise. For example, many teams collect CPH numbers but have no way to validate it's correct. Rather than creating a new CPH number component and letting it sit in your codebase for just your team, see our contribution guide to learn how to contribute this back to DXT for everyone to benefit from.

Step 1: Add forms-engine-plugin as a dependency

Installation

npm install @defra/forms-engine-plugin --save

Dependencies

The following are plugin dependencies that are required to be registered with hapi:

npm install hapi-pino @hapi/crumb @hapi/yar @hapi/vision --save

Additional npm dependencies that you will need are:

npm install nunjucks govuk-frontend --save

Optional dependencies

npm install @hapi/inert --save

  • @hapi/inert - static file and directory handlers for serving GOV.UK assets and styles

Step 2: Register DXT as a hapi plugin

import plugin from '@defra/forms-engine-plugin'
await server.register({
  plugin,
  options: {
    // if applicable
  }
})

Full example:

import hapi from '@hapi/hapi'
import yar from '@hapi/yar'
import crumb from '@hapi/crumb'
import inert from '@hapi/inert'
import pino from 'hapi-pino'
import plugin from '@defra/forms-engine-plugin'

const server = hapi.server({
  port: 3000
})

// Register the dependent plugins
await server.register(pino)
await server.register(inert)
await server.register(crumb)
await server.register({
  plugin: yar,
  options: {
    cookieOptions: {
      password: 'ENTER_YOUR_SESSION_COOKIE_PASSWORD_HERE' // Must be > 32 chars
    }
  }
})

const viewPaths = [join(config.get('appDir'), 'views')]

// Register the `forms-engine-plugin`
await server.register({
  plugin,
  options: {
    cacheName: 'session', // must match a session you've instantiated in your hapi server config
    /**
     * Options that DXT uses to render Nunjucks templates
     */
    nunjucks: {
      basePageLayout: 'your-base-layout.html', // the base page layout. Usually based off https://design-system.service.gov.uk/styles/page-template/
      viewPaths // list of directories DXT should use to render your views. Must contain basePageLayout.
    },
    /**
     * Services is what DXT uses to interact with external APIs
     */
    services: {
      formsService, // where your forms should be downloaded from.
      formSubmissionService, // handles temporary storage of file uploads
      outputService // where your form should be submitted to
    },
    /**
     * View context attributes made available to your pages. Returns an object containing an arbitrary set of key-value pairs.
     */
    viewContext: (request) => {
      "example": "hello world" // available to render on a nunjucks page as {{ example }}
    }
  }
})

await server.start()

Step 3: Handling static assets

TODO: CSS will be updated with a proper build process using SASS.

  1. Update webpack to bundle the DXT application assets (CSS, JavaScript, etc)
  2. Serve the newly bundled assets from your web server

DXT plans to prefix to these asset paths to prevent collisions with your assets. Contact #defra-forms-support if this is a blocker for you.

Step 4: Environment variables

Blocks marked with # FEATURE: <name> are optional and can be omitted if the feature is not used.

# START FEATURE: Phase banner -- supports `https://` and `mailto:` links in the feedback link
FEEDBACK_LINK=http://test.com
# END FEATURE: Phase banner

# START FEATURE: DXT -- used if using DXT's infrastructure for file uploads
DESIGNER_URL=http://localhost:3000
SUBMISSION_URL=http://localhost:3002

# S3 bucket and URL of the CDP uploader. Bucket is owned by DXT, uploader is your service's URL.
UPLOADER_BUCKET_NAME=my-bucket
UPLOADER_URL=http://localhost:7337
# END FEATURE: DXT

# START FEATURE: GOV.UK Notify -- used if using DXT's default GOV.UK Notify email sender
NOTIFY_TEMPLATE_ID="your-gov-notify-api-key"
NOTIFY_API_KEY="your-gov-notify-api-key"
# END FEATURE: GOV.UK Notify

# START FEATURE: Google Analytics -- if enabled, shows a cookie banner and includes GA on the cookies/privacy policy
GOOGLE_ANALYTICS_TRACKING_ID='12345'
# END FEATURE: Google Analytics

Step 5: Creating and loading a form

Forms in DXT are represented by a JSON configuration file. The configuration defines several top-level elements:

The form-engine-plugin uses JSON configuration files to serve form journeys. These files are called Form definitions and are built up of:

  • pages - includes a path, title
  • components - one or more questions on a page
  • conditions - used to conditionally show and hide pages and
  • lists - data used to in selection fields like Select, Checkboxes and Radios

To understand the full set of options available to you, consult our schema documentation. Specifically, the form definition schema.