Skip to main content
U.S. flag

An official website of the United States government

Dot gov

The .gov means it’s official.
Federal government websites often end in .gov or .mil. Before sharing sensitive information, make sure you’re on a federal government site.

Https

The site is secure.
The https:// ensures that you are connecting to the official website and that any information you provide is encrypted and transmitted securely.

About

Using Web Components

Web Components are a set of web platform APIs that allow you to create new custom, reusable, encapsulated HTML tags to use in web pages and web apps.

How to use a web component

A web component looks like an HTML element such as <va-example-component>. It has unique styling and functionality and can work in any JavaScript framework or library. The fact that these components are framework agnostic, helps us future proof our component library.

Web Components consist of three parts:

  • A custom HTML element
    • Where you register your own HTML tag
  • The shadow DOM
    • This is a separate DOM node tree for your custom HTML elements that includes scoped CSS styles
  • Templates and Slots
    • You write HTML templates that you can add to your HTML elements
    • You add slots to provide additional context within the component

React and Web Components

Use our VA Design System Web Components where applicable in your projects. We maintain this component library to provide VA teams with an ecosystem of vetted and tested components.

While large portions of VA.gov are built via React applications, there are some teams that cannot import React directly into their projects and have to add work around hacks in order to use React components.

Due to these issues the Design System Team has moved to using Web Components on VA.gov applications and pages.

For easy identification, all of our Web Components begin with a va- prefix. For example, the Web Component version of our alert component is named va-alert (or VaAlert as the React binding).

The benefits of using Design System Web Components include:

  • Web Components can be imported into any JS Framework
  • Consistent syntax across frameworks and projects
  • Actively updated and maintained - we are deprecating most React components and they will not have the latest updates
  • Performance and speed

The Design System Team has specific linting and migration rules in place to help ease in the transition from React to Web Components. We also encourage all developers use Design System Components in their applications instead of creating their own similar components.

If our components do not meet your needs, we would love to hear about it. Reach out to us in Slack at #platform-design-system or submit a bug report. And if you are interested in contributing to the Design System, review how to contribute a new component to the design system.

USWDS V1 to V3 migration

The current version of the Design System is compatible with the US Web Design System (USWDS) version 1. To use components compatible with version 3 of the USWDS, add a uswds flag to the component, as in this example:

<va-gizmo uswds>

To check if the component you want to use has a v3 version, go to the VA Design System’s Storybook site and look under the “USWDS” section. Here you will find a list of available components as well as implementation details and examples.

To migrate, if the uswds prop has been set to false, explicitly set it to true. Run all of your application test suites and address any tests that break due to migration.

Vanilla JavaScript applications

If a Design System web component will be used without the need for passing in a function, object, array, or custom event, you are ready to use it without any additional imports.

A vanilla web component is used like <va-example-component> (identified by tags prefixed with <va-*>).

We make our best efforts to avoid creating web components with object or array properties in order to make them easier to use in static HTML pages.

React applications

React application have an option of either using the web component directly like <va-example-component> or importing the React binding for the web component which would look like this <VaExampleComponent>. Both of these implementations render as web components though.

How to choose to use the vanilla component or React binding?

If either of these are true, we would recommend using the React binding for ease of use:

  • You must pass in a function, object or array to a web component’s properties
  • You must use custom events

If you are not sure if you need either of those features, refer to the web component’s Storybook documentation to review its events and properties.

Importing a React binding of a web component

Bindings are component wrappers that allow our web components to work as first-class React components. This allows them to handle custom events and to pass in more than primitives to a web component’s properties.

Example of importing the React binding of a web component:


import {
  VaExampleComponent
} from "@department-of-veterans-affairs/component-library/dist/react-bindings";

const exampleFunction = () => { return "Hello, World!" };

<VaExampleComponent exampleProp={exampleFunction} />

The equivalent vanilla Web Component version using <va-example-component> would be this:


<script>
  const component = document.querySelector('va-example-component');
  const exampleFunction = () => { return "Hello, World!" };
  component.exampleProp = exampleFunction();
</script>

<va-example-component />

It can be more convenient to use the React binding version of the Web Component in React when a function is needed to be passed into a prop. But if you don’t require passing in a function or listening to events, use the vanilla Web Component and avoid an import entirely.

Custom Events

Some of the Design System Web Components allow for custom events.

If the Web Component has a custom event that you need to use and you’re using the React binding, you will need to prefix events with on. Given an event named vaChange, use onVaChange.


import {
  VaExampleComponent
} from "@department-of-veterans-affairs/component-library/dist/react-bindings";

const exampleCallback = (event) => { console.log(event.detail) }

<VaExampleComponent onVaChange={exampleCallback} />

If the Web Component has a custom event that you need to use and you’re not using the React binding, you will add an event listener using the event name as the event type:


<script>
  const element = document.querySelector('va-example-component');
  const exampleCallback = event => { console.log(event.detail) }
  element.addEventListener('vaChange', exampleCallback)
</script>

<va-example-component>

The majority of our web components also fire a component-library-analytics event used to send component library interactions into analytics data layer events. The handler for the Google Analytics event exists in vets-website.

For more information about custom events for specific components, refer to the Storybook documentation.

Native Events

Some of our web components utilize native HTML DOM events such as click and blur. We prefer to use native events when possible because it is easier for teams to test and may not require the use of React bindings.

To use native events in JSX, they must be prefixed with on and use camel case. Given the native blur event, use onBlur.

An example using the click event in JSX:


<va-button text="Edit" onClick={ (event) => console.log(event.detail) } />

To use native events in vanilla JavaScript, they can be used inline and prefixed with on or by adding an event listener using the event name as the event type.

An example using the blur event in vanilla JavaScript:


<va-button onblur="handleBlur()" />

Another example using the blur event in vanilla JavaScript:


<script>
  const element = document.querySelector('va-button');
  element.addEventListener('blur', (event) => { console.log(event.detail) })
</script>

<va-button>

For more information about native events in a specific component, refer to the Storybook documentation.

Edit this page in GitHub (Permissions required)
Last updated: Nov 08, 2024