---
title: Installation
description: >-
  Survicate offers several installation methods to choose from, depending on
  your needs and preferences
source_url:
  html: 'https://developers.survicate.com/javascript/installation/'
  md: 'https://developers.survicate.com/javascript/installation.md'
---
# Installation

## Overview

Survicate offers several installation methods to choose from, depending on your needs and preferences:

- Manual JavaScript code installation
- Survicate Web Package
- Survicate Web Surveys Wrapper
- Via Segment
- Wordpress Plugin
- Google Tag Manager Plugin
- Braze

### Manual implementation

By opting for Manual implementation or utilizing the Survicate Web Surveys Wrapper, you ensure automatic access to the latest SDK version. These methods negate the need for frequent updates whenever Survicate releases new SDK features.

### NPM packages

Survicate offers two NPM packages for integrating surveys into your JavaScript applications: the Survicate Web Package, designed for embedding surveys directly within your code, and the Survicate Web Surveys Wrapper, optimized for easy installation of Survicate's tracking code in your codebase.
- [Survicate Web Package on npmJS](https://www.npmjs.com/package/@survicate/survicate-web-package)
- [Survicate Web Surveys Wrapper on npmJS](https://www.npmjs.com/package/@survicate/survicate-web-surveys-wrapper)

### Comparison: Web Package vs. Web Surveys Wrapper

| Feature                       | Web Package                                        | Web Surveys Wrapper                                       |
| ------------------------------| ---------------------------------------------------| ----------------------------------------------------------|
| **Integration Type**          | Direct integration in JavaScript applications      | Installation of Survicate tracking code                   |
| **HTML Impact**      | Does not add any script to the HTML document       | Adds script to the HTML document                          |
| **Security**                  | Prioritizes security, no external scripts required | -                                                         |
| **TypeScript Support**        | Includes TypeScript type definitions               | Includes TypeScript type definitions                      |
| **Version Updates**           | Manual updates for new SDK versions                | Automatically uses the latest Survicate SDK version       |

## Workspace Key
Workspace key is a unique identifier of your teamspace on Survicate account. It will be needed to complete the installation. Your workspace key can be obtained via your Survicate account [here](https://panel.survicate.com/o/0/w/0/settings/access-keys)

## Installation methods

### Manual implementation

Place this code right before the `</body>` tag of your website or web app.

```html
<!-- Start of Survicate (www.survicate.com) code -->
<script type="text/javascript">
  (function (w) {
    var s = document.createElement('script');
    s.src = 'https://survey.survicate.com/workspaces/{{YOUR WORKSPACE KEY HERE}}/web_surveys.js';
    s.async = true;
    var e = document.getElementsByTagName('script')[0];
    e.parentNode.insertBefore(s, e);
  })(window);
</script>
<!-- End of Survicate code -->
```

Information about the code being installed is sent to Survicate the moment your site is loaded with our code on it.

To verify installation on your own, you can use the _svc method in the browser console. It should return your Workspace Key.

### NPM packages
This section applies only to users, who decided to install Survicate tracking code either via the npm web surveys package, or npm wrapper.

**Installation**

```bash title="Web package"
npm install @survicate/survicate-web-package --save
```

```bash title="Web surveys wrapper"
npm install @survicate/survicate-web-surveys-wrapper --save
```

**Initialization**

```javascript title="Web package"
import Survicate from '@survicate/survicate-web-package/survicate_widget'

const key = "workspace key" // Your key from the panel

Survicate.init({workspaceKey: key});
```

```javascript title="Web surveys wrapper"
import { initSurvicate } from '@survicate/survicate-web-surveys-wrapper/widget_wrapper';

const config = { workspaceKey: 'workspace key' }; // Your key from the panel

await initSurvicate(config)
```

### Segment

Survicate can be installed with Segment. Follow [these instructions](https://help.survicate.com/en/articles/3942525-segment-integration#installing-survicate-tracking-code-with-segment), to add Survicate as a destination in Segment.

### WordPress

Use our WordPress plugin to install Survicate on your WordPress website. Follow [these instructions](https://help.survicate.com/en/articles/3937898-installing-survicate-on-wordpress-sites) and use this workspace key during the installation.

### Google Tag Manager

To install Survicate using Google Tag Manager, follow [this article](https://help.survicate.com/en/articles/3937897-google-tag-manager).

### Braze

To install Survicate using Braze, follow [this article](https://help.survicate.com/en/articles/9060740-braze-integration).

Braze in-app messages are displayed in an iframe by default while the app's background is blocked. To allow interaction with your app, while Survicate surveys are displayed, you need to:

1. Add `opts.useBrazeIframeClipper = true` to your Survicate-Braze snippet.

A sample snippet:

```html
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body class="survicate-body survicate-survey">
  <script type="text/javascript">
    (function(opts) {
      opts.traits = {
        "braze_id": "{{${BRAZE_ID}}}",
        "braze_survey_id": "BRAZE_SURVEY_ID",
        "email": "{{${email_address}}}",
        "version": "2"
      };
      opts.useBrazeIframeClipper = true;
      opts.forcedLanguage = "pl"; // Optional to override the survey language: ISO 639-1 language code (e.g., "en", "de", "fr", "es", "pl")
    })(window._sva = window._sva || {});

    (function(w) {
      var s = document.createElement('script');
      s.src = 'https://survey.survicate.com/workspaces/{WORKSPACE_KEY}/web_surveys.js';
      s.async = true;
      var e = document.getElementsByTagName('script')[0];
      e.parentNode.insertBefore(s, e);
    })(window);
  </script>
</body>
</html>
```
2. Integrate the Braze bridge using one of the following options:

   - **NPM package**: Install `@survicate/braze-bridge-npm` [package](https://www.npmjs.com/package/@survicate/braze-bridge-npm) in the file where you initialize Braze and use the `initBrazeBridge` function.
   - **Script snippet**: Add the following script to your page. With `data-auto-init="true"`, the Braze bridge will be automatically launched:

   ```html
   <script src="https://surveys-static-prd.survicate-cdn.com/braze_bridge.js" data-auto-init="true"></script>
   ```

   A sample React implementation (NPM package):
```javascript
import { initBrazeBridge } from '@survicate/braze-bridge-npm';

  const setupBraze = () => {
      braze.changeUser('user@survicate.com');
      braze.subscribeToInAppMessage((message) => {
      braze.showInAppMessage(message);
    });

    braze.automaticallyShowInAppMessages();
    braze.openSession();
  };

  const initializeBraze = () => {
    if (braze.isInitialized()) return;

    braze.initialize('BRAZE_APP_ID', {
      baseUrl: 'BRAZE_BASE_URL',
      enableLogging: true,
      allowUserSuppliedJavascript: true
    });
  }

  useEffect(() => {
    initBrazeBridge();
    initializeBraze();
    setupBraze();
  }, []);
```

## Users identification

Each time a user answers a Survicate survey they're assigned a unique, anonymous ID. For most companies it makes sense to have these responses identified. To do so, you can pass user IDs and attributes from your website or web app.

Here's a sample implementation:

```javascript title="Manual implementation"
// Define user IDs before the init of the tracking code.
(function(opts) {
  opts.traits = {
    "user_id": "Your user ID here"
  };
})(window._sva = window._sva || {});

// Your tracking code goes here
```

```javascript title="Web package"
const traits = {'user_id': 'Your user ID here'};

Survicate.setVisitorTraits(traits);
```

```javascript title="Web surveys wrapper"
// Initialize survicate, then use:
const survicate = getSurvicateInstance();
const traits = {'user_id': 'Your user ID here'};

// Set user attributes
survicate.setVisitorTraits(traits);
```

## User attributes
Survicate lets you also pass other attributes. Attributes provide deeper insight into collected feedback. You can use them to target the right audiences and filter survey results. Some example attributes that can be passed to Survicate are:

- Company name
- Subscription name
- Signed up date

User attributes can be seen on their profile in the respondents tab.

### Supported Attribute Types
- **String**: Any textual data, e.g. company names, user name, etc.
- **Numbers**: Includes integers and decimals, both positive and negative.
- **Boolean**: True or false values.
- **Date**: Accepts date objects created using `Date()` constructor: `new Date('1995-12-17T03:24:00')` or dates in ISO 8601 format (e.g., `YYYY-MM-DDTHH:MM:SSZ`).

***Important to note:***
- Attribute name and value can have max length of 255 characters. Longer values will be truncated to 255 characters.
- Strings should not be enclosed within the following characters: {}, *, [], %, ~, --, $ (e.g., 'name':'$john$').
- Attribute names are case sensitive.

To pass user attributes to Survicate and use them for survey targeting, you should define these attributes when initializing Survicate.
Please note that attribute names are case-sensitive, whereas attribute values are not.

```javascript title="Manual implementation"
// Define attributes when initializing the tracking code
(function(opts) {
  opts.traits = {
    "user_id": "Your user ID here",
    "company_name": "Value here",
    "subscription_status": "Value here",
    "signed_up": "Value here"
  };
})(window._sva = window._sva || {});

/// Your tracking code goes here
```

```javascript title="Web package"
const config = {
  workspaceKey: 'workspace key',
  traits: {
    'user_id': 'Your user ID here',
    'company_name': 'Value here',
    'subscription_status': 'Value here',
    'signed_up': 'Value here'
  }
};

Survicate.init(config);
```

```javascript title="Web surveys wrapper"
const config = {
  workspaceKey: 'workspace key',
  traits: {
    'user_id': 'Your user ID here',
    'company_name': 'Value here',
    'subscription_status': 'Value here',
    'signed_up': 'Value here'
  }
};

await initSurvicate(config);
```

## Survey language

By default, Survicate automatically detects the appropriate survey language using the following priority:

1. **`<html lang>` attribute** - the language your page declares on its `<html>` element (only when enabled via [`useHtmlLangAttribute`](#detect-language-from-the-html-lang-attribute))
2. **URL language** - query parameters (e.g., `?lang=de`), path segments (e.g., `/de/page`), or top-level domain (e.g., `.de`)
3. **Browser language** - the user's browser language settings

You can override this automatic detection by setting a forced language during initialization. This is useful when you know the user's preferred language from your application's settings or user profile.

```javascript title="Manual implementation"
(function(opts) {
  opts.forcedLanguage = "de"; // ISO 639-1 language code (e.g., "en", "de", "fr", "es", "pt-br")
})(window._sva = window._sva || {});

// Your tracking code goes here
```

```javascript title="Web package"
import Survicate from '@survicate/survicate-web-package/survicate_widget'

const config = {
  workspaceKey: 'workspace key', // Your key from the panel
  forcedLanguage: 'de' // ISO 639-1 language code (e.g., "en", "de", "fr", "es", "pt-br")
};

Survicate.init(config);
```

```javascript title="Web surveys wrapper"
import { initSurvicate } from '@survicate/survicate-web-surveys-wrapper/widget_wrapper';

const config = {
  workspaceKey: 'workspace key', // Your key from the panel
  forcedLanguage: 'de' // ISO 639-1 language code (e.g., "en", "de", "fr", "es", "pt-br")
};

await initSurvicate(config);
```

***Important to note:***
- Forced language has the highest priority and overrides URL-based and browser-based language detection.
- Forced language is session-based, so it will be applied only for the current session.
- If user sets "pt-br" as language code, and only "pt" is available in your survey's translations, the survey will display in "pt" language.
- If user sets "pt" as language code, and "pt-br" is available in your survey's translations, the survey will display in "pt-br" language.
- The language code should be a valid [ISO 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) code (e.g., `en`, `de`, `fr`, `es`, `pt`).
- The specified language must be available in your survey's translations. If the language is not available, the survey will display in its default language.
- To change the language dynamically after initialization, use the [`setSurveyLanguage`](/javascript/methods#set-survey-language) method.

### Detect language from the html lang attribute

If your site declares its current language through the standard `lang` attribute on the `<html>` element, you can opt in to using it as a language detection source with `useHtmlLangAttribute`. This is especially useful for single-page applications with an in-app language switcher, where the selected language is never reflected in the URL and the browser language may not match what the user picked.

```javascript title="Manual implementation"
(function(opts) {
  opts.useHtmlLangAttribute = true; // read the survey language from <html lang="...">
})(window._sva = window._sva || {});

// Your tracking code goes here
```

```javascript title="Web package"
import Survicate from '@survicate/survicate-web-package/survicate_widget'

const config = {
  workspaceKey: 'workspace key', // Your key from the panel
  useHtmlLangAttribute: true // read the survey language from <html lang="...">
};

Survicate.init(config);
```

```javascript title="Web surveys wrapper"
import { initSurvicate } from '@survicate/survicate-web-surveys-wrapper/widget_wrapper';

const config = {
  workspaceKey: 'workspace key', // Your key from the panel
  useHtmlLangAttribute: true // read the survey language from <html lang="...">
};

await initSurvicate(config);
```

***Important to note:***
- The option is opt-in and off by default — without it, language detection works exactly as described above.
- When enabled, the `<html lang>` value is checked after a forced language ([`forcedLanguage`](#survey-language) / [`setSurveyLanguage`](/javascript/methods#set-survey-language)) but before URL-based and browser-based detection.
- Language changes are picked up live: when your application updates the `<html lang>` attribute (e.g., the user switches the language in your app, with no page reload), a survey that is currently open re-renders in the new language and any survey shown later uses it too.
- An explicit language choice always wins: a language set via `setSurveyLanguage` or picked by the respondent in the survey's language selector is not overridden by later `<html lang>` changes.
- If the `<html lang>` value has no matching survey translation, detection falls back to URL, browser, and default language as usual.
- The option applies to website surveys (widget and feedback button).

## Survey theme

By default, Survicate uses the `"auto"` theme mode, which follows the browser preference (light or dark). You can override this by setting a theme mode during initialization. This is useful when you want surveys to match your website's theme from the first load.

Allowed values for `themeMode` are:
- **`"light"`** – force surveys to use the light theme
- **`"dark"`** – force surveys to use the dark theme

For the dark theme to be applied, the survey's theme must have a dark mode variant configured in the Survicate panel.

```javascript title="Manual implementation"
(function(opts) {
  opts.themeMode = "dark"; // "light", "dark"
})(window._sva = window._sva || {});

// Your tracking code goes here
```

```javascript title="Web package"
import Survicate from '@survicate/survicate-web-package/survicate_widget'

const config = {
  workspaceKey: 'workspace key', // Your key from the panel
  themeMode: 'dark' // "light", "dark"
};

Survicate.init(config);
```

```javascript title="Web surveys wrapper"
import { initSurvicate } from '@survicate/survicate-web-surveys-wrapper/widget_wrapper';

const config = {
  workspaceKey: 'workspace key', // Your key from the panel
  themeMode: 'dark' // "light", "dark"
};

await initSurvicate(config);
```

***Important to note:***
- Theme mode is applied when the survey loads; behavior matches the [`setThemeMode`](/javascript/methods#set-theme-mode) method but is set at init.
- To change the theme dynamically after initialization, use the [`setThemeMode`](/javascript/methods#set-theme-mode) method.

## Content Security Policy (CSP)

Content Security Policy (CSP) serves as a safeguard against code injection attacks,
where harmful content is executed within a trusted webpage.
However, this security measure may interfere with the functionality of Survicate on your site.
If you use CSP, you should update it with the following directives
to ensure Survicate's surveys work effectively without compromising security:

```text
script-src 'unsafe-inline' https://survey.survicate.com https://surveys-static.survicate.com https://surveys-static-prd.survicate-cdn.com https://survey-prd.survicate-cdn.com;
style-src 'unsafe-inline' https://surveys-static.survicate.com https://surveys-static-prd.survicate-cdn.com;
style-src-elem 'unsafe-inline' https://surveys-static.survicate.com https://surveys-static-prd.survicate-cdn.com;
font-src https://surveys-static.survicate.com https://surveys-static-prd.survicate-cdn.com;
img-src https://surveys-static.survicate.com https://surveys-static-prd.survicate-cdn.com https://assets.survicate.com https://img.survicate.com https://images.unsplash.com;
connect-src https://respondent.survicate.com https://hv.survicate.com https://survey.survicate.com https://survey-prd.survicate-cdn.com https://production-respondent-uploads.s3.eu-west-1.amazonaws.com https://surveys-static.survicate.com https://surveys-static-prd.survicate-cdn.com;
```

### Reducing the policy length

If you are constrained by header size limits, you can shorten the policy in two ways.

**Option 1 — Use wildcard subdomains**

Replace the explicit subdomain lists with wildcard patterns. This reduces the policy by approximately 40%. Note that the full explicit list above is stricter — it allows only the exact subdomains Survicate currently uses, whereas wildcards would also cover any other subdomain under `survicate.com` and `survicate-cdn.com`.

```text
script-src 'unsafe-inline' https://*.survicate.com https://*.survicate-cdn.com;
style-src 'unsafe-inline' https://*.survicate.com https://*.survicate-cdn.com;
style-src-elem 'unsafe-inline' https://*.survicate.com https://*.survicate-cdn.com;
font-src https://*.survicate.com https://*.survicate-cdn.com;
img-src https://*.survicate.com https://*.survicate-cdn.com https://images.unsplash.com;
connect-src https://*.survicate.com https://*.survicate-cdn.com https://production-respondent-uploads.s3.eu-west-1.amazonaws.com;
```

**Option 2 — Remove entries that don't apply to your setup**

Depending on your installation method and the features you use, some entries are not required:

- **`script-src` Survicate domains** — only needed when loading Survicate via the remote script tag or the `@survicate/survicate-web-surveys-wrapper` NPM package. If you use the `@survicate/survicate-web-package` NPM package, no external scripts are fetched from Survicate servers, so you can remove the Survicate domains from `script-src` entirely.
- **`img-src https://images.unsplash.com`** — only needed if your surveys contain images sourced from Unsplash (e.g. a background image selected from the Unsplash library in the survey editor). If none of your surveys use Unsplash images, you can remove this entry.
- **`connect-src https://production-respondent-uploads.s3.eu-west-1.amazonaws.com`** — only needed if your surveys include a screenshot question. If you don't use the screenshot feature, you can remove this entry.

### Nonce

Survicate allows users to implement nonce as an additional security measure when embedding scripts. A nonce (number used once) helps mitigate certain types of attacks, such as Cross-Site Scripting (XSS), by ensuring that each script request is authorized.

**How to implement nonce with different installation types**

```javascript title="Manual implementation"
  <script type="text/javascript" nonce="{{YOUR NONCE}}">
    (function(opts) {
      opts.nonce = "{{YOUR NONCE}}";
    })(window._sva = window._sva || {});

    (function(w) {
      var c = document.createElement("script");
      c.src = "https://survey.survicate.com/workspaces/{{YOUR WORKSPACE KEY HERE}}/web_surveys.js";
      c.async = true;
      var s = document.getElementsByTagName("script")[0];
      s.parentNode.insertBefore(c, s);
    })(window);
  </script>
```

```javascript title="Web package"
  import Survicate from '@survicate/survicate-web-package/survicate_widget'

  const config = {
    workspaceKey: 'workspace key'  // Your key from the panel
    nonce: 'nonce' // Your nonce
  };

  Survicate.init(config);
```

```javascript title="Web surveys wrapper"
  import { initSurvicate } from '@survicate/survicate-web-surveys-wrapper/widget_wrapper';

  const config = {
    workspaceKey: 'workspace key'  // Your key from the panel
    nonce: 'nonce' // Your nonce
  };

  await initSurvicate(config)
```

### Disable sensitive data persistence

The Disable Sensitive Data Persistence feature ensures that user data is stored only in Session Storage, not Local Storage. This means data is cleared when the browser or tab is closed, enhancing privacy by preventing long-term storage of sensitive information.

```javascript title="Manual implementation"
  <script type="text/javascript">
    (function(opts) {
      opts.disableSensitiveDataPersistence = true;
    })(window._sva = window._sva || {});

    (function(w) {
      var c = document.createElement("script");
      c.src = "https://survey.survicate.com/workspaces/{{YOUR WORKSPACE KEY HERE}}/web_surveys.js";
      c.async = true;
      var s = document.getElementsByTagName("script")[0];
      s.parentNode.insertBefore(c, s);
    })(window);
  </script>
```

```javascript title="Web package"
  import Survicate from '@survicate/survicate-web-package/survicate_widget'

  const config = {
    workspaceKey: 'workspace key'  // Your key from the panel
    disableSensitiveDataPersistence: true
  };

  Survicate.init(config);
```

```javascript title="Web surveys wrapper"
  import { initSurvicate } from '@survicate/survicate-web-surveys-wrapper/widget_wrapper';

  const config = {
    workspaceKey: 'workspace key'  // Your key from the panel
    disableSensitiveDataPersistence: true
  };

  await initSurvicate(config)
```
