# Components

Shift4 Components are web UI elements that securely collect sensitive information (like card number, expiration, and CVC for card payments) in your payment forms. The use of Shift4 ensures that sensitive payment data never touches your server or your website.

To use Shift4 Components you need to include `Shift4.js` library and initialize it with your public key:

```html
<script type="text/javascript" src="https://js.dev.shift4.com/shift4.js"></script>

<script type="text/javascript">
  // Initialize Shift4 object with your public key
  var shift4 = Shift4("pu_test_WVMFC9GFuvm54b0uorifKkCh");
</script>
```

Once the library is configured, there are two ways to use Shift4 Components to collect card data:

- use separate components for number, expiry, and CVC
- use a single component for all card details


Please check our guidelines for CSP [here](/docs/csp-integration).

## Single component for all card details

This approach is the fastest and easiest to implement. It is also preferred when you have limited space for a payment form.

First, you need to create a placeholder tag in the HTML code of your website:

```html
<div id="card"></div>
```

Then in JavaScript code, you need to create a Single Line and mount it to that placeholder tag:

```javascript
var card = shift4.createComponent("card").mount("#card");
```

Later, when all card data have been provided by a customer, you need to create a token from that Single Line:

```javascript
shift4.createToken(card).then(/*...*/).catch(/*...*/);
```

Complete and working code can be found in our Single Line example.

## Separate components for number, expiry and CVC

When you want full control over your payment form, you can use separate components for each field. This approach requires little more code than using a single component, but it is also fast and easy to implement.

First, you need to create a placeholder tag for each component. To simplify the creation of components, we group these placeholders under one common tag, and we used the `data-shift4` attribute to specify a type of component:

```html
<div id="payment-form">
    <div data-shift4="number"></div>
    <div data-shift4="expiry"></div>
    <div data-shift4="cvc"></div>
</div>
```

Doing it this way allows to create of a component group and automatically creates and mounts all components in that group:

```javascript
var components = shift4.createComponentGroup().automount("#payment-form");
```

Later, when all card data have been provided by a customer, you need to create a token from that component group:

```javascript
shift4.createToken(components).then(/*...*/).catch(/*...*/);
```

Complete and working code can be found in our Custom Form example.

## Creating components manually

An alternative approach to using the `data-shift4` attribute and `automount` method is to manually create each component. To do this, you don't need to have a common parent element, but you need some other way to locate placeholder tags (for example, using the `id` attribute):

```html
<div id="number"></div>
<div id="expiry"></div>
<div id="cvc"></div>
```

Then in JavaScript, you need to create a component group and then create and mount each component in that group:

```javascript
var components = shift4.createComponentGroup();
components.createComponent("number").mount("#number");
components.createComponent("expiry").mount("#expiry");
components.createComponent("cvc").mount("#cvc");
```

## Using separate component for expiration month and year

Another alternative possibility is to use two components for the card expiration date - separate components for expiration month and year.

To do so, you must create two placeholder tags and use component types `expiryMonth` and `expiryYear`. It can be done by using `data-shift4` attribute and `automount()` or manual component creation.

## Component styling

You can customize the visuals of Shift4 components on your webpage by setting the `height`, `style` and `fonts` attributes in options. The options are applicable either to a single component or a component group. They are merged but only for top level attributes, ie.: `finalOptions = {...componentGroupOptions, ...componentOptions}`.

For the full list of supported style properties, pseudo-classes and font attributes, see [Styling](/docs/js/styling) in the JS reference.

```javascript
let shift4 = Shift4("pu_test_WVMFC9GFuvm54b0uorifKkCh");

let options = {
  height: '38px',
  style: {
    base: {
      color: '#44d',
      fontSize: '30px',
      fontFamily: 'Orbitron',
      '::placeholder': {
        color: '#99f'
      },
    },
    invalid: {
      color: '#f00',
      '::placeholder': {
        color: '#f99'
      },
    }
  },
  fonts: [{
    family: 'Orbitron',
    style: 'normal',
    weight: 400,
    display: 'swap',
    src: "url(https://fonts.gstatic.com/s/orbitron/v25/yMJRMIlzdpvBhQQL_Qq7dy0.woff2) format('woff2');"
  }]
};

let components = shift4.createComponentGroup(options);
let number = components.createComponent("number").mount("#number");
let expiry = components.createComponent("expiry").mount("#expiry");
let cvc = components.createComponent("cvc").mount("#cvc");
```

The `createComponent()` method accepts an optional second argument with options for that single component - `createComponent("expiry", { height: '48px' })`. The placeholder to render into is never passed to `createComponent()`; it is always given to `mount()`.

## Adding an event listener

It is possible to attach an Event Listener using `on` method to listen for the change event. You will need to specify the event type as `change` and provide a handler function that will be executed when the event occurs.

In the handler function, you can access properties such as `empty`, `error`, and `cardBrand` to determine the state of the component when the change event is triggered.

The following piece of code exemplifies blocking a flow based on a card brand.

```javascript
var card = shift4.createComponent("card").mount("#card");
card.on('change', event => {
  if (event.cardBrand !== "visa") {
    // disable the button
  } else {
    // enable the button
  }
})
```