> For the complete documentation index, see [llms.txt](https://docs.wproofreader.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.wproofreader.com/v6.18.1/integrations/initialization/sdk-integration-guide.md).

# SDK integration guide

End-to-end path from credentials to a working WProofreader integration, with links to the detailed pages for each step.

This guide walks through a complete WProofreader SDK integration in the order you actually do it: get your credentials, pick an integration method, point the SDK at the right service endpoint, then add it to your page. Each step links to the page that covers it in depth.

It applies to:

* **cloud version**, where requests are processed by the WebSpellChecker cloud;
* **self-hosted admin panel**, where requests are processed by your own WProofreader application;
* **self-hosted without the admin panel**, which has no Service ID. Everything here still applies: skip [step 1](#step-1-get-your-service-id) and configure the service endpoint only.

The Service ID is issued and stored by the admin panel, so it exists only where the admin panel and its database are deployed. Apart from that, what differs between the three is the service endpoint, covered in [step 3](#step-3-configure-the-service-endpoint).

{% hint style="info" %}
Already know the basics and just need a parameter? Go straight to [Service connection](/v6.18.1/integrations/initialization/configuration-options/service-connection.md) or the full [configuration reference](https://webspellchecker.com/docs/api/wscbundle/Options.html).
{% endhint %}

***

### Step 1. Get your Service ID

The Service ID is the activation key of your subscription. It is generated for you when the subscription is created, it is static, and it stays the same across your environments.

1. Sign in to the admin panel and open the **Credentials** page:
   * Cloud: [app.wproofreader.com/credentials](https://app.wproofreader.com/credentials).
   * Self-hosted admin panel: served from your own host, `http(s)://<your_host_name>:<port>/credentials`. By default the admin panel has no virtual directory, so the path follows the port directly.
2. Click the eye icon to reveal the **Service ID**, then copy it with the copy button.

<div align="left"><figure><img src="https://content.gitbook.com/content/iyQMCOvN8kKwZftNXZft/blobs/GZgQjEaEYhLxOh5x2AlA/Credentials%20page%20showing%20Service%20ID%20and%20Access%20key%20fields.png" alt="Credentials page showing Service ID and Access key fields" width="563"><figcaption><p>The Credentials page in the cloud admin panel</p></figcaption></figure></div>

The **Access key** on the same page is a different credential, used to authenticate direct API requests. You don't need it for SDK setup. Full description of both: [Credentials](/v6.18.1/admin-panel/credentials.md).

{% hint style="warning" %}
The Service ID is visible in the page source of your application, so it is protected by domain restrictions rather than by secrecy. Add every domain that will run WProofreader under **Settings > Domain permissions** in the admin panel, including your staging and development hosts. In the cloud, that page is at [app.wproofreader.com/settings](https://app.wproofreader.com/settings).

Separate Service IDs per environment are not issued. See [Can we obtain a separate service ID for our development environment?](/v6.18.1/faq/general/licensing/can-we-obtain-a-separate-service-id-for-our-development-environment.md)
{% endhint %}

***

### Step 2. Choose an integration method

| Method       | Best for                                                                                                                 |
| ------------ | ------------------------------------------------------------------------------------------------------------------------ |
| Script-based | Quick setup without a build process. Add the config and script to your HTML page.                                        |
| NPM SDK      | JavaScript framework projects (React, Angular, Vue) or setups with multiple editors sharing one proofreading dependency. |

Both methods expose the same options and the same `WEBSPELLCHECKER` global. The choice is about how the bundle reaches the browser, not about functionality.

Within either method you then choose how instances are created: `autoSearch`, an explicit `init()` call, or the `data-wsc-autocreate` attribute. All three are described in [Initialization options](/v6.18.1/integrations/initialization/initialization-options.md).

***

### Step 3. Configure the service endpoint

This is the part that differs between cloud and self-hosted, and the most common reason an integration silently does nothing. The Service ID identifies your subscription wherever you have one. What self-hosted adds is the four `service*` options that tell the SDK where your own server is, since requests must not go to the cloud. Which option applies where:

| Option            | Cloud    | Self-hosted                                          |
| ----------------- | -------- | ---------------------------------------------------- |
| `serviceId`       | Required | Required with the admin panel, not used without it   |
| `serviceProtocol` | Not used | Required, `http` or `https`                          |
| `serviceHost`     | Not used | Required, host name of your WProofreader application |
| `servicePort`     | Not used | Required, `443` for HTTPS on the default port        |
| `servicePath`     | Not used | Required, `wscservice/api` by default                |

{% hint style="warning" %}
Set `serviceId` whenever you have one. For self-hosted, always set the four `service*` options as well, otherwise the SDK has no address for your own server. A missing or incomplete service configuration is the usual reason WProofreader loads but never checks anything.
{% endhint %}

#### Bundle URL

The URL the `wscbundle.js` script is loaded from isn't a configuration option, but it is part of the endpoint setup. For cloud, the address of the service is derived from it, so serving the bundle from `svc.webspellchecker.net` is what points the SDK at the cloud. For self-hosted, serve it from your own host.

| Deployment  | Bundle URL                                                                         |
| ----------- | ---------------------------------------------------------------------------------- |
| Cloud       | `https://svc.webspellchecker.net/spellcheck31/wscbundle/wscbundle.js`              |
| Self-hosted | `http(s)://<your_host_name>:<wproofreader_port>/wscservice/wscbundle/wscbundle.js` |

For self-hosted, substitute your own protocol, host, port, and virtual directory. A server running at `wproofreader.example.com` with the default virtual directory serves the bundle at:

```
http(s)://wproofreader.example.com:<wproofreader_port>/wscservice/wscbundle/wscbundle.js
```

Set the URL as the `src` attribute of the script tag, or as the `srcUrl` option with the npm SDK.

For the exact snippets of each option, and for passing an `Authorization` header with `requestHeaders` and `withCredentials` when your service sits behind authentication, see [Service connection](/v6.18.1/integrations/initialization/configuration-options/service-connection.md). Complete working examples with these options already in place are in [step 4](#step-4-add-wproofreader-to-your-page).

***

### Step 4. Add WProofreader to your page

The two examples below are minimal and complete, and cover the script-based setup for cloud and for self-hosted. Every other environment already has a dedicated guide with a full example in it, so this step links to those rather than repeating them.

#### Script-based, cloud

Define the configuration before the bundle loads, then load `wscbundle.js` from the cloud.

{% code overflow="wrap" fullWidth="true" %}

```html
<script>
  window.WEBSPELLCHECKER_CONFIG = {
    autoSearch: true,
    lang: 'en_US',
    serviceId: 'your-service-ID'
  };
</script>

<textarea>This sample text demonstrates WProofreader in a textarea.</textarea>

<script src="https://svc.webspellchecker.net/spellcheck31/wscbundle/wscbundle.js"></script>
```

{% endcode %}

With `autoSearch` enabled, proofreading starts as soon as the user focuses any supported editable field. Place the configuration and the script inside `<body>`, ideally right before the closing tag.

Other ways to create instances, including `init()` and `data-wsc-autocreate`: [Initialization options](/v6.18.1/integrations/initialization/initialization-options.md).

{% hint style="info" %}
Inline `data-wsc-*` attributes cover a subset of the options. Define `serviceId` in `WEBSPELLCHECKER_CONFIG`, which supports the full set.
{% endhint %}

#### Script-based, self-hosted

Same structure, with the endpoint options added next to `serviceId` and the bundle served from your host. Without the admin panel, drop the `serviceId` line and keep the rest.

{% code overflow="wrap" fullWidth="true" %}

```html
<script>
  window.WEBSPELLCHECKER_CONFIG = {
    autoSearch: true,
    lang: 'en_US',
    serviceId: 'your-service-ID',
    serviceProtocol: 'https',
    serviceHost: 'your_host_name',
    servicePort: '443',
    servicePath: 'wscservice/api'
  };
</script>

<textarea>This sample text demonstrates WProofreader in a textarea.</textarea>

<script src="https://your_host_name/wscservice/wscbundle/wscbundle.js"></script>
```

{% endcode %}

#### Other environments

The same options apply everywhere, only the place you put them changes. Each guide below shows them in a complete example, for both cloud and self-hosted.

| Environment                                                  | Guide                                                                                                                                                                                                                                                                                                                                                                                                            |
| ------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| React, Angular, Vue, or any project with a build step        | [Initialize using npm SDK](/v6.18.1/integrations/initialization/initialization-options/initialize-using-npm-sdk.md), and [JavaScript frameworks](/v6.18.1/integrations/javascript-frameworks.md) for where to place the script                                                                                                                                                                                   |
| Rich text editors                                            | [CKEditor 5](/v6.18.1/integrations/rich-text-editors/ckeditor-5.md), [CKEditor 4](/v6.18.1/integrations/rich-text-editors/ckeditor-4.md), [Froala Editor](/v6.18.1/integrations/rich-text-editors/froala-editor.md), [TinyMCE 6+](/v6.18.1/integrations/rich-text-editors/tinymce-6+.md), [Tiptap](/v6.18.1/integrations/rich-text-editors/tiptap.md), [Quill](/v6.18.1/integrations/rich-text-editors/quill.md) |
| `<textarea>`, `<div contenteditable>`, `<iframe>`, `<input>` | [HTML editable elements](/v6.18.1/integrations/html-editable-elements.md). Note that `<input>` is excluded from `autoSearch` by default                                                                                                                                                                                                                                                                          |
| Content management systems                                   | [Drupal](/v6.18.1/integrations/drupal.md), [WordPress](/v6.18.1/integrations/wordpress.md), [Moodle](/v6.18.1/integrations/moodle.md), [Learnosity](/v6.18.1/integrations/learnosity.md)                                                                                                                                                                                                                         |

👉 Working examples for every editor: [demos](https://demos.webspellchecker.com/).

***

### Step 5. Verify the integration

1. Open a page with an editable field and type a misspelled word, for example `sampl`. It should be underlined, and clicking it should open the suggestion pop-up.
2. Open the browser developer tools and check the **Network** tab. Requests to the service endpoint should return `200`.
3. Check the **Console** tab for warnings about a missing service configuration or an unsupported language code.

For self-hosted deployments you can also confirm the server itself is reachable with the [health check](/v6.18.1/api-reference/auxiliary-api-commands/health-check.md) command before looking at the client side.

Common problems and their causes:

* [Often issues while configuring Cloud services](/v6.18.1/troubleshooting/client-side/often-issues-while-configuring-cloud-services.md) covers `403` product errors, unsupported language codes, and similar.
* [CORS policy: no Access-Control-Allow-Origin header](/v6.18.1/troubleshooting/client-side/cors-policy-no-access-control-allow-origin-header-is-present-on-the-requested-resource.md) for cross-origin self-hosted setups.
* [Overview of HTTP response status codes](/v6.18.1/troubleshooting/client-side/overview-of-http-response-status-codes.md).
* [How to access the browser console errors and failed requests in the network tab](/v6.18.1/troubleshooting/client-side/how-to-access-the-browser-console-errors-and-failed-requests-in-the-network-tab.md) walks through steps 2 and 3 in detail, and shows how to export a HAR file if you need to send the failing request to support.

***

### Where to go next

Once the integration works, tune it with the [configuration options](/v6.18.1/integrations/initialization/configuration-options.md):

* [Startup and behavior](/v6.18.1/integrations/initialization/configuration-options/startup-and-behavior.md) for how and when instances are created.
* [Languages and dictionaries](/v6.18.1/integrations/initialization/configuration-options/languages-and-dictionaries.md) for the default language, language detection, and custom dictionaries.
* [Check types](/v6.18.1/integrations/initialization/configuration-options/check-types.md) for spelling, grammar, style guide, and autocorrect.
* [UI elements](/v6.18.1/integrations/initialization/configuration-options/ui-elements.md) for the badge, suggestion pop-up, dialog, and settings.
* [Callbacks](/v6.18.1/integrations/initialization/configuration-options/callbacks.md) to hook into WProofreader events from your application.
* [Latency and execution speed “debounce mechanism”](/v6.18.1/integrations/initialization/latency-and-execution-speed-debounce-mechanism.md) for tuning request frequency.

The complete list of options lives in the [configuration reference](https://webspellchecker.com/docs/api/wscbundle/Options.html).
