---
title: Implement Token Vault code
description: There are three main components to configure when implementing the Token Vault. It is important the configuration is consistent between these components. To achieve this, you could add your shared configuration to a .env file in the root of your project.
component: sdks
version: latest
page_id: sdks:token-vault:getting-started/03-implement-token-vault-code
canonical_url: https://docs.pingidentity.com/sdks/latest/token-vault/getting-started/03-implement-token-vault-code.html
revdate: Tue, 18 Jul 2023 14:37:51 +0100
keywords: ["Setup &amp; Configuration", "OAuth 2.0", "Integration", "Source Code"]
section_ids:
  implement_main_app_code: Implement main app code
  implement_token_vault_interceptor_code: Implement Token Vault Interceptor code
  implement_token_vault_proxy_code: Implement Token Vault Proxy code
  build_the_code: Build the code
  bundling_the_interceptor: Bundling the Interceptor
  next_steps: Next steps
---

# Implement Token Vault code

There are three main components to configure when implementing the Token Vault. It is important the configuration is consistent between these components. To achieve this, you could add your shared configuration to a `.env` file in the root of your project.

In the following examples, the configuration uses literal values to help understand the values required.

## Implement main app code

This configuration should be within your app's `index` or `main` file.

Initialize the Token Vault client:

`app/src/main.js`

```javascript
import { Config, TokenManager } from '@forgerock/javascript-sdk';
import { client } from '@forgerock/token-vault';

/**
 * This factory function takes in a config object and returns
 * the necessary methods to setup the iframe ("proxy"), the
 * service worker ("interceptor"), and the token store replacement
 * API ("store").
 */
const register = client({
    app: {
        origin: 'https://app.example.com',
    },
    interceptor: {
        file: '/interceptor.js',
    },
    proxy: {
        origin: 'https://proxy.example.com',
    },
});

/**
 * Sets up the service worker for intercepting fetch requests
 */
register.interceptor({
    /* optional interceptor worker config */
});

/**
 * Injects the iframe into the DOM to setup the proxy
 * Make sure to pass in the required, real DOM element as the zeroeth argument
 */
register.proxy(document.getElementById('token-vault'), {
    /* optional proxy config */
});

/**
 * Creates the store replacement for the SDK
 */
const tokenVaultStore = register.store({
    /* optional store config */
});
```

In the same file, [configure the SDK](../../sdks/configure-the-sdks.html):

`app/src/main.js`

```javascript
Config.setAsync({
  clientId: 'ForgeRockSDKClient',
  redirectUri: location.href,
  scope: 'openid profile email address',
  serverConfig: {
    wellknown: 'https://openam-forgerock-sdks.forgeblocks.com/am/oauth2/realms/root/realms/alpha/.well-known/openid-configuration',
    timeout: 5000,
  },
  realmPath: 'alpha',
  // Replace the default token store with Token Vault's store
  tokenStore: tokenVaultStore,
});
```

## Implement Token Vault Interceptor code

This configuration should be within the Service Worker's entry file, which is separate from your main application code.

This is also the file to which your `client()` method config object property of `interceptor.file` method references.

Reference this file in your main application when calling the `client()` method, as the `interceptor.file` property.

Example configuration is as follows:

`app/interceptor/interceptor.js`

```javascript
import { interceptor } from '@forgerock/token-vault';

interceptor({
  interceptor: {
    // Use either fully qualified URLs
    // Or end with a single asterisk as a wildcard
    urls: [/* Your protected endpoint URLs */],
  },
  forgerock: {
    // MUST match what you configured in your main app
    serverConfig: {
      baseUrl: 'https://openam-forgerock-sdks.forgeblocks.com/am',
      timeout: 5000,
    },
    realmPath: 'alpha',
  },
});
```

|   |                                                                                                                                                                                                                                                                                                                                                                |
| - | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|   | The `interceptor.urls` array accepts a `/*` ending to match any request from a particular root domain and path. This means you do not have to list each and every unique protected endpoint that your app might use.For example, `https://backend.example.com/resources/protected/*`This is not a full glob-pattern feature - just a single trailing wildcard. |

## Implement Token Vault Proxy code

This configuration should be within the Token Vault Proxy entry file.

Example configuration is as follows:

`proxy/src/proxy.js`

```javascript
import { proxy } from '@forgerock/token-vault';

proxy({
  app: {
    // This MUST match the origin where your main app runs
    origin: 'https://app.example.com',
  },
  forgerock: {
    //  MUST match the config in your main app and interceptor
    clientId: 'ForgeRockSDKClient',
    redirectUri: location.href,
    scope: 'openid profile email address',
    serverConfig: {
      baseUrl: 'https://openam-forgerock-sdks.forgeblocks.com/am',
      timeout: 5000,
    },
    realmPath: 'alpha',
  },
});
```

## Build the code

The Token Vault requires more complex building and bundling configuration than a regular JavaScript app that uses the SDK because it requires three different bundles:

1. The main application

2. The Token Vault Interceptor (Service Worker)

3. The Token Vault Proxy (iframe)

You can often use a default configuration for the main application and the Token Vault Proxy when using any of the popular bundlers, such as *Webpack* or *Vite*

The Token Vault Interceptor requires a specific build configuration to ensure maximum compatibility with various browsers.

## Bundling the Interceptor

To provide the best cross-browser support, the Token Vault Interceptor requires a dedicated bundle configuration so that it results in a single-file output, down-leveled to at least ES2020 without *any* ES Module syntax.

We recommend using a separate `vite.interceptor.config.js` or `webpack.interceptor.config.js` for the Token Vault Interceptor, as well as a build separate command that consumes this separate configuration file.

|   |                                                                                                                                                                                           |
| - | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|   | If you are using Vite, you might achieve the best results with [bundling into an Immediately Invoked Function Expression (IIFE)](https://vitejs.dev/config/build-options.html#build-lib). |

If you are using Webpack, its defaults are good for bundling the Token Vault Interceptor.

## Next steps

After you implement the code to enable the Token Vault, you can update your app to obtain tokens using origin isolation.
