# Configuration

In order to load and render Show\.js simply include a JavaScript tag and then invoke the library.

## Add Show\.js script to the page <a href="#add-showjs-script-to-the-page" id="add-showjs-script-to-the-page"></a>

Add the following script tag to the webpage that will render the data to your customer:

PCI 4.0 RequirementsWith the introduction of PCI DSS version 4.0, a new requirement has been put forth to ensure the integrity of scripts that run on payment pages. Script Integrity is crucial in maintaining the security and trustworthiness of online payment systems, as any unauthorized modifications to these scripts could potentially lead to data breaches or fraudulent activities. To meet this requirement, organizations must implement mechanisms to verify the integrity of each script utilized on their payment pages. To get a hash of a specific version, visit this [page](/vault/developer-tools/vgs-show/js/changelog.md#ensuring-script-integrity-for-pci-compliance).

```html
<script type="text/javascript" src="https://js.verygoodvault.com/vgs-show/2.2.2/show.js" integrity="sha384-70nFlhYfZpPZ0nh4E9kRCT2HXORAKatDFQXQP8Dxq8motfd35aSMMu9g6VE/oAIV" crossorigin="anonymous"></script>
```

In your HTML create an empty wrapper element and assign it your own unique identifier (we've used "secret-data" here, but you can assign your own UID). This element defines the place where the iframe will be inserted:

*Example:*

```html
<div id="secret-data">Iframe with revealed data would be here!</div>HTML
```

## Initialize Show\.js

Use the following code to create VGS Show instance:

```javascript
const show = VGSShow.create('<VAULT_ID>', (state) => { console.log(state) })
                    .setEnvironment('<ENVIRONMENT>');
```

* [.create()](/vault/developer-tools/vgs-show/js/reference-documentation.md#api-vgscollectcreate)
* [.setEnvironment()](/vault/developer-tools/vgs-show/js/reference-documentation.md#api-showsetenvironment)
* [Reference Documentation](/vault/developer-tools/vgs-show/js/reference-documentation.md)

## Configure HTTP request

Use the `.request()` method to configure HTTP requests to your backend:

**Example**

{% tabs %}
{% tab title="POST/JSON" %}

```javascript
const frame = show.request({
  name: 'secret-card-number',
  method: 'POST',
  path: '/secure-data',
  payload: {'card_number': '<ALIAS>'},
  htmlWrapper: 'text',
  jsonPathSelector: 'json.card_number'
});
```

{% endtab %}

{% tab title="GET/JSON" %}

```javascript
const frame = show.request({
  name: 'secret-image',
  method: 'GET',
  path: '/get',
  type: 'image',
  htmlWrapper: 'image',
  jsonPathSelector: 'json.image'
});
```

{% endtab %}

{% tab title="POST/FormData" %}

```javascript
const bodyFormData = new FormData();
bodyFormData.append('card_number', '<ALIAS>');
const show = VGSShow.create('<VAULT_ID>', function(state) {})
                    .setEnvironment('<ENVIRONMENT>');
const frame = show.request({
  name: 'secret-card-number',
  method: 'POST',
  path: '/secure-data',
  payload: bodyFormData,
  htmlWrapper: 'text',
  headers: { 'Content-Type': 'multipart/form-data' }
});
frame.render('#secret-data', { fontWeight: 'bold', color: 'blue' });
      
```

{% endtab %}
{% endtabs %}

### Authorization methods

There are multiple options for how you can authorize a Show\.js request:

* Via [Cookies](#vgs-showjs-and-cookies):

```javascript
show.request({
  withCredentials: true,
  ...
});
```

* Via \`Authorization\` header in the \`show\.request()\` method:

```javascript
show.request({
  headers: {
    'Authorization': <token>
  }
});
```

Please also check that the server responds with the `Access-Control-Allow-` headers.

* Via API Key as a header or as a query parameter in the `show.request()` method:

{% tabs %}
{% tab title="Header" %}

```javascript
show.request({
  headers: {
    'X-API-Key': <key>
  }
});
```

{% endtab %}

{% tab title="Query String" %}

```javascript
show.request({
  path: '/endpoint?api_key=<key>'
});
```

{% endtab %}
{% endtabs %}

* [.request()](/vault/developer-tools/vgs-show/js/reference-documentation.md#api-showsetcname-1)
* [Reference Documentation](/vault/developer-tools/vgs-show/js/reference-documentation.md)

## Render secure frame

Use the `.render()` method to insert the Show\.js iframe somewhere on your page. It takes two arguments: a CSS selector identifying where the iframe will be rendered on the page and an object with custom styles that will be applied to the revealed value.

*Example:*

{% tabs %}
{% tab title="Styling " %}

```javascript

iframe.render('#secret-data', {
  'font-family': 'Arial, sans-serif',
  'color': 'white',
  'font-size': '14px',
  '&:hover': {
    'color': 'red',
  }
});
    
```

{% endtab %}

{% tab title="@font-face" %}

```javascript

iframe.render('#secret-data', {
  '@font-face': {
    'font-family': 'PT Mono',
    'font-style': 'normal',
    'font-weight': '400',
    'font-display': 'swap',
    'src': 'local("PT Mono"), local("PTMono-Regular") url(https://fonts.gstatic.com/s/ptmono/v7/9oRONYoBnWILk-9AnCszM_HxEcn7Hg.woff2) format("woff2")',
    'unicode-range': 'U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116'
  },
  'font-family': '"PT Mono", monospace',
  'color': 'white',
  'font-size': '14px',
});
```

{% endtab %}

{% tab title="base64 encode @font-face" %}

```javascript

iframe.render('#secret-data', {
  '@font-face': {
    'font-family': 'CustomFont',
    'src': 'url(data:application/x-font-woff;charset=utf-8;base64,<base64 encoded string>,format("woff"))',
  },
  'font-family': 'CustomFont',
  'color': 'white',
  'font-size': '14px',
});
```

{% endtab %}
{% endtabs %}

* [.render()](/vault/developer-tools/vgs-show/js/reference-documentation.md#api-showsetcname-3)
* [Reference Documentation](/vault/developer-tools/vgs-show/js/reference-documentation.md)

## Subscribe to changes

Listen to events and handle different states in callback functions.

```javascript

frame.on('requestSuccess', function() {
  console.log('HTTP request was successfully completed!');
});
frame.on('requestFail', function(error) {
  const errorStatus = error.status || 'Uknown error status code';
  console.log('The request failed with ', errorStatus);
  console.log(error.message);
});
frame.on('revealSuccess', function() {
  console.log('Reveal opeation successfully was completed. Secure value revealed!');
});
frame.on('revealFail', function() {
  console.log('Reveal opeation was failed in the iframe!');
});
frame.render('#secret-data', { fontWeight: 'bold', color: 'blue' });\n
  
```

* [.on()](/vault/developer-tools/vgs-show/js/reference-documentation.md#api-showsetcname-4)
* [.off()](/vault/developer-tools/vgs-show/js/reference-documentation.md#api-showsetcname-5)
* [Reference Documentation](/vault/developer-tools/vgs-show/js/reference-documentation.md)

## Copy to clipboard button

In order to improve and simplify UX for the end-user, Show\.js provides the ability to copy data from the iframe to the clipboard buffer. The button itself is located in a separate iframe and is fully customizable.

### Step 1. Create dependency

Use `.copyFrom()` method to set the target iframe (you want to copy data from) and configurethe  button.

> Iframe with revealed data should be initialized **before** the copy button.

*Example:*

```javascript

  const show = VGSShow.create('<VAULT_ID>' function(state) {})
                    .setEnvironment('<ENVIRONMENT>');\n
  const cardNumber = show.request({
    name: 'secret-card-number',
    method: 'POST',
    path: '/secure-data',
    payload: {'card_number': '<ALIAS>'},
    htmlWrapper: 'text',
  });\n
  const copyButton = show.copyFrom(cardNumber, { text: 'My copy button' }, (status) => {
      if (status === 'Success') {
        alert('Copied!')
      }
  });
  
```

* [.copyFrom()](/vault/developer-tools/vgs-show/js/reference-documentation.md#api-showsetcname-2)
* [Reference Documentation](/vault/developer-tools/vgs-show/js/reference-documentation.md)

### 2. Render button

Render copy to clipboard button.

*Example:*

```javascript
const show = VGSShow.create('<VAULT_ID>' function(state) {})
                  .setEnvironment('<ENVIRONMENT>');
const cardNumber = show.request({
  name: 'secret-card-number',
  method: 'POST',
  path: '/secure-data',
  payload: {'card_number': '<ALIAS>'},
  htmlWrapper: 'text',
});
cardNumber.render('#secret-data', { fontWeight: 'bold', color: 'blue' });\n
const copyButton = show.copyFrom(cardNumber, { text: 'My copy button' }, (status) => {
    if (status === 'Success') {
      alert('Copied!')
    }
});
copyButton.render('#place-for-copy-button', {
  '@font-face': {
    'font-family': 'PT Mono',
    'font-style': 'normal',
    'font-weight': '400',
    'font-display': 'swap',
    'src': 'local("PT Mono"), local("PTMono-Regular") url(https://fonts.gstatic.com/s/ptmono/v7/9oRONYoBnWILk-9AnCszM_HxEcn7Hg.woff2) format("woff2")',
    'unicode-range': 'U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116'
  },
  'font-family': '"PT Mono", monospace',
  'padding': '10px',
  'background-color': 'red',
  'font-size': '12px',
  'color': 'white',
});
```

* [.render()](/vault/developer-tools/vgs-show/js/reference-documentation.md#api-showsetcname-3)
* [Reference Documentation](/vault/developer-tools/vgs-show/js/reference-documentation.md)

## Data formatting

You have the ability to format received data or the value being copied to the clipboard via `serializers` property.

### .replace()

Returns a new string with some or all matches of an old value replaced by the new value. Under the hood, using native [String.prototype.replace()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace) JS method.

*Examples:*

```javascript
const cardNumber = show.request({
  ...
  // separate card number with dashes 4111111111111111 -> 4111-1111-1111-1111
  serializers: [show.SERIALIZERS.replace('(\\d{4})(\\d{4})(\\d{4})(\\d{4})', '$1-$2-$3-$4')],
  // separate card number with spaces 4111111111111111 -> 4111 1111 1111 1111
  serializers: [show.SERIALIZERS.replace('(\\d{4})(\\d{4})(\\d{4})(\\d{4})', '$1 $2 $3 $4')],
  // remove spaces 4111 1111 1111 1111 -> 4111111111111111
  serializers: [show.SERIALIZERS.replace(' ', '')],
  // remove first 2 dashes 4111-1111-1111-1111 -> 411111111111-1111
  serializers: [show.SERIALIZERS.replace('-', "", 2)],
});
```

```javascript
const copyBtn = show.copyFrom(cardNumber,
  {
    text: 'Copy',
    // remove dashes from value when copying data to clipboard 4111-1111-1111-1111 -> 41111111111111111
    serializers: [show.SERIALIZERS.replace('-', "")],
  },
  function (status) {
    if (status === 'success') {
      alert('Copied!');
    }
});
```

* [.request()](/vault/developer-tools/vgs-show/js/reference-documentation.md#api-showsetcname-1)
* [.copyFrom()](/vault/developer-tools/vgs-show/js/reference-documentation.md#api-showsetcname-2)
* [Reference Documentation](/vault/developer-tools/vgs-show/js/reference-documentation.md)

## VGS Show\.js with CNAMEs

When integrated with VGS, by default, the traffic is passed via the VGS proxy, which has `tntxxxxx.sandbox.verygoodproxy.com` format, where `tntxxxxx` is your Vault identifier.\
VGS Show\.js allows you to set your own hostname and make requests to the non-VGS domain name.

Before adding a new Hostname, you should create a CNAME record for your existing domain in your DNS provider’s account that should point to `<VAULT_ID>.<ENVIRONMENT>.verygoodproxy.com`.

> Learn more about [custom hostnames.](/vault/http-proxy/inbound-connection/custom-hostnames.md)

Go to the `Vault Settings` on the [Dashboard](https://dashboard.verygoodsecurity.com/dashboard/v/current/settings/custom-hostnames) and add a Custom Hostname, then click on the `Activate for SDKs` button.

![Custom hostnames](/files/jdBoNgjKUg9F2lmSBmZJ)

Once the CNAME is turned on, specify the custom hostname domain using `.setCname()` method, and you're all set. Now, traffic will go through the defined CNAME.

**Example:**

```javascript
const show = VGSShow.create('<VAULT_ID>', (state) => {})
                    .setEnvironment('<ENVIRONMENT>')
                    .setCname('my-cname.com')
  
```

* [.setCname()](/vault/developer-tools/vgs-show/js/reference-documentation.md#api-showsetcname)
* [Reference Documentation](/vault/developer-tools/vgs-show/js/reference-documentation.md)

## VGS Show\.js with Cookies

If you would like to pass cookies to your server along with the request made from the Show\.js, make sure you've done all the steps from the list below:

* You can't share cookies across domains. You may share across subdomains. Matching rules for the domain require the cookie `Domain` to match the host to which the request is being made. Configure and use [CNAME](#showjs-with-cnames) in your integration with Show\.js. Your application and API must have the same origin; otherwise, the browser will not attach them to the request. Custom Hostnames allows making a Vault accessible at a non-VGS domain name (for example, [www.customdomain.com](http://www.customdomain.com)). So any requests made through VGS will now reflect your domain alias.\
  \
  Example:\
  `.myawesomesite.com` - your application domain.\
  `.vgs.myawesomesite.com` - CNAME configured and used as a request URL domain.
* Add an additional `withCredentials: true` property in the `show.request()` method which will indicate that the request should be made using credentials such as cookies or authorization headers:\\

```javascript
show.request({
    ...,
    withCredentials: true
});
```

* Make sure you have added `SameSite=None` and `Secure` attributes to the `Set-Cookie` header:\
  `Set-Cookie: flavor=choco; Domain=.myawesomesite.com; Secure; HttpOnly; SameSite=None`
* Please also check that the server responds with the `Access-Control-Allow-Credentials` header. Responding with this header to `true` means that the server allows cookies (or other user credentials) to be included on cross-origin requests.

> - Adding \`SameSite=None\` disable the protection from CSRF. Instead CSRF will need to be guarded against through one time use tokens or similar means.
> - Be aware of requests done to other origins which may result in the users cookie now being shared.

## Configuration example

{% code title="Client" %}

```html
<body>
  <main>
    <!-- Iframe wrapper -->
    <div id="secret-data"></div>
  </main>
  <!-- Show.js script file -->
  <script type="text/javascript" src="https://js.verygoodvault.com/vgs-show/2.0.0/<organization-id>.js"></script>
  <script>
    // Show.js initialization
    const show = VGSShow.create('<VAULT_ID>', function(state) {
        console.log(state);
    }).setEnvironment('<ENVIRONMENT>');
    // Request configuration
    const iframe = show.request({
      name: 'secret-card-number',
      method: 'POST',
      path: '/secure-data',
      payload: {'card_number': '<alias>'},
      htmlWrapper: 'text',
      jsonPathSelector: 'json.card_number'
    });
    // iframe rendering
    iframe.render('#secret-data', { fontWeight: 'bold', color: 'blue' });
  </script>
</body>
```

{% endcode %}

{% code title="Server" %}

```javascript
route('/get-secret-data', method="POST", function(request, response) {
  // User authentication is required
  if (authenticationSuccess()) {
    response.status(200).send(<alias>);
  } else {
    response.status(403);
  }
});
```

{% endcode %}

### VGS Show on mobile

Here is a demo of how VGS Show\.js can be integrated into your mobile application via WebView:

* [VGS Show.js + React Native](https://snack.expo.io/@verygoodfiddle/show.js) example

### Code examples

* [Reveal image](https://jsfiddle.net/VeryGoodFiddle/6d4cpn7v/) example
* [Add custom font](https://jsfiddle.net/VeryGoodFiddle/zgse8vft/) example
* [Copy button](https://jsfiddle.net/VeryGoodFiddle/r0mdou2e/) example
* [Base64 font rendering](https://jsfiddle.net/VeryGoodFiddle/xv0zcoyg/) example
* [VGS Show.js + React](https://jsfiddle.net/VeryGoodFiddle/bL1k946c/) example
* [VGS Show.js card styling](https://jsfiddle.net/VeryGoodFiddle/9r6npazs/) example


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.verygoodsecurity.com/vault/developer-tools/vgs-show/js/configuration.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
