# Achla AI — documentation for AI agents > How to install the Achla AI search widget on a website, verify it, and diagnose problems by their AISX-… codes. Full text: https://achlaai.com/llms-full.txt - Install: https://achlaai.com/en/docs/install (Markdown: https://achlaai.com/docs/install.md) - Troubleshooting: https://achlaai.com/en/docs/troubleshooting (Markdown: https://achlaai.com/docs/troubleshooting.md) --- # Install Achla AI on a website > How to add the Achla AI search widget to a website (HTML, WordPress, Drupal, single-page apps), choose a placement mode, and verify the installation. HTML: https://achlaai.com/en/docs/install · Markdown: https://achlaai.com/docs/install.md ## Short answer for AI agents - **What:** one ``. The real key (starts with `pk_`) is in the Achla AI dashboard under **Settings → Embed code**. - **Where:** in the HTML of every page that should have search, just before ``, exactly once per page. - **WordPress / Drupal:** prefer the official plugin ([WordPress.org](https://wordpress.org/plugins/achlaai/), [Drupal.org](https://www.drupal.org/project/achlaai_search)) over pasting the tag. - **Inline mode** needs `` on the page; **attach mode** needs a CSS selector of an existing search ``. Default (bubble) needs nothing else. - **Verify:** `curl -s "https://achlaai.com/api/widget-config?key=YOUR_PUBLIC_KEY"` must return `"enabled":true`; the browser console must show no `[ai-search]` lines; a test question must return an answer with sources. - **Always finish by verifying** — see [Verify the installation](#verify). - **Something wrong:** every console message starts with `[ai-search] AISX-…` — look the code up in [Troubleshooting](https://achlaai.com/en/docs/troubleshooting) ([Markdown](https://achlaai.com/docs/troubleshooting.md)). ## Prerequisites The widget shows itself only after the server explicitly enables it for the key. That requires all of the following, set up in the dashboard: - An account with Achla AI, with the site registered. - Site ownership verified (via the widget tag or a CMS plugin connection). - An active plan (paid subscription or the Free plan). - The first indexing of the site finished — **Overview** in the dashboard shows the status. Check from any terminal (no login needed — the key is public): ```bash curl -s "https://achlaai.com/api/widget-config?key=YOUR_PUBLIC_KEY" ``` - `{"enabled":true,"config":{…}}` — ready; the widget will appear wherever the tag is installed. - `{"enabled":false}` — key unknown or replaced, project not active, index not ready, or ownership/plugin connection invalid. The dashboard shows project, indexing and connection status; a stale or deleted key is not flagged there — compare the key in the tag with **Settings → Embed code** first ([AISX-W110](https://achlaai.com/en/docs/troubleshooting#AISX-W110)). - `{"error":"bad_request"}` (HTTP 400) — the key value is malformed ([AISX-W112](https://achlaai.com/en/docs/troubleshooting#AISX-W112)). ## The embed snippet Replace `YOUR_PUBLIC_KEY` with the key from **Settings → Embed code** (or copy the whole tag from there). ```html ``` | Attribute | Required | Values | Purpose | | --- | --- | --- | --- | | `src` | yes | `https://achlaai.com/w.js` | The widget. It sends its API requests to the same origin it was loaded from — do not copy the file to your own server or CDN. | | `data-key` | yes | public key, starts with `pk_` | Identifies the site. Missing → [AISX-W101](https://achlaai.com/en/docs/troubleshooting#AISX-W101); malformed → [AISX-W112](https://achlaai.com/en/docs/troubleshooting#AISX-W112). | | `defer` | recommended | — | Load without blocking the page; the widget mounts once the document is ready. | | `data-mode` | no | `bubble` · `inline` · `attach` | Overrides the placement mode chosen in the dashboard, for this tag only. | | `data-attach` | no | CSS selector | The search `` to attach to (used with `attach` mode); overrides the dashboard selector. | | `data-position` | no | `br` · `bl` · `tr` · `tl` | Corner of the floating button (bubble): bottom-right, bottom-left, top-right, top-left. | | `data-preview` | never on a live site | `1` | Dashboard preview only: the widget makes no network requests and answers with a canned demo. | > **Which setting wins.** The tag controls **placement only** (`data-mode`, `data-attach`, `data-position`). Everything visual — theme, accent colour, corner radius, title, placeholder, greeting — comes from the dashboard via the server and cannot be set in the tag. Placement attributes you omit (or give an unknown value) fall back to the dashboard setting. - Put the tag in the HTML of every page that should show search, just before ``. - Exactly **one** tag per page. A second copy mounts a second widget ([AISX-W105](https://achlaai.com/en/docs/troubleshooting#AISX-W105)). - If you add the tag with JavaScript, set `data-key` and the other `data-*` attributes before appending it to the page. ## Placement modes | Mode | What visitors see | Requirement on the page | If the requirement is missing | | --- | --- | --- | --- | | `bubble` (default) | A floating “Ask AI” button in a corner that opens a chat panel. | None. | — | | `inline` | A search box embedded in your content. | An element `` in the page HTML. | Floating button instead + [AISX-W104](https://achlaai.com/en/docs/troubleshooting#AISX-W104). | | `attach` | Your existing search field opens AI answers in a dropdown on Enter, with a link back to your regular results. | A CSS selector that matches an `` of type `text` or `search`. | Floating button instead + [AISX-W102](https://achlaai.com/en/docs/troubleshooting#AISX-W102) / [AISX-W103](https://achlaai.com/en/docs/troubleshooting#AISX-W103) / [AISX-W106](https://achlaai.com/en/docs/troubleshooting#AISX-W106). | > **Switching to inline? Add the container first.** Changing the mode to `inline` in the dashboard reaches every page within about 30 seconds ([when changes take effect](https://achlaai.com/en/docs/troubleshooting#changes-take-effect)). Pages without `` fall back to the floating button. The container must be in the page when the widget mounts; one added later by client-side code is not picked up. For `attach`, only the first element matched by the selector is used. Test the selector on the live page in the browser console: `document.querySelector('input[type="search"]')` (replace with your selector) must return your search input. Dashboard changes to mode or selector need no cache purge — see [When do changes take effect?](https://achlaai.com/en/docs/troubleshooting#changes-take-effect). > **CMS plugins use one placement mode for the whole site.** The WordPress plugin and the Drupal module each have a single placement setting for the whole site. In **Bubble** or **Attach** they load the widget on every public page; in **Inline** they load it only on pages that contain the shortcode/block, and all other pages get no widget at all (no floating button). A floating button everywhere plus an inline box on one page is not possible with the plugins — use manual tags for that (below). ### Mixed placement with manual tags (bubble everywhere, inline on one page) With manual tags this works, because `data-mode` on the tag overrides the dashboard mode for that tag: 1. Keep the dashboard mode at **Bubble**. 2. On all pages except the target page, use the normal tag (no `data-mode`). 3. On the target page, use a single tag with `data-mode="inline"` and add `` where the box should appear. 4. Never put two widget tags on one page — the second copy mounts a second widget ([AISX-W105](https://achlaai.com/en/docs/troubleshooting#AISX-W105), install-check [AISX-C303](https://achlaai.com/en/docs/troubleshooting#AISX-C303)). Target page only — this tag replaces the normal one there. ```html ``` ## Install paths ### Plain HTML / any server-rendered site 1. Copy the tag from **Settings → Embed code** in the dashboard. 2. Paste it into the shared layout/template of your site, just before ``, so it is on every page. 3. For inline mode, also add `` where the search box should appear. 4. Deploy, purge any page cache/CDN cache for the HTML, then run the checks in [Verify the installation](#verify). ### WordPress — official plugin (recommended) 1. Install **Achla AI Search for WordPress** from [WordPress.org](https://wordpress.org/plugins/achlaai/) (current version 0.3.5): **Plugins → Add New**, or upload the ZIP. 2. Activate it, open **Settings → Achla AI Search** and select **Connect**. 3. Complete the ownership step on Achla AI, return to WordPress and wait for the connection and indexing status. 4. Keep **Bubble** placement or choose **Inline** or **Attach** (test an Attach selector before saving), then switch **Show the widget** on. 5. Inline: insert the shortcode `[achla_search]` or the block **Achla AI Search** (`achlaai/inline-search`) on the pages where the search box should appear — it outputs the `#ai-search` container for you. > **Note.** The plugin loads the widget through its own loader script (not a `/w.js` tag), so a `grep` for `/w.js` will not find it. The plugin uses **one placement mode for the whole site**: with **Inline** it loads the widget only on pages that contain the shortcode or block — other pages show nothing (no floating button) and no console message is printed; in **Bubble** or **Attach** the shortcode/block outputs nothing. For a floating button everywhere plus an inline box on one page, use manual tags instead of the plugin ([Mixed placement](#mixed-placement)). Do not also paste the manual tag while the plugin is active. ### WordPress — manual tag (without the plugin) Paste the tag into your theme's footer template just before ``, or use a header/footer code-snippet plugin that outputs it on every page. Use either this or the official plugin, never both. ### Drupal — official module 1. Install **Achla AI Search for Drupal** (Drupal 10.3+ and 11.3+, PHP 8.1+): `composer require 'drupal/achlaai_search:^0.3'`. A ZIP is also available on [Drupal.org](https://www.drupal.org/project/achlaai_search). 2. Enable the module `achlaai_search` (Extend page, or `drush en achlaai_search`). 3. Open **Administration → Configuration → Web services → Achla AI Search** (`/admin/config/services/achlaai-search`) and connect the site. 4. Choose placement: **Bubble**, **Inline** (place the block **Achla AI Search** in a region via Block layout), or **Attach** (the selector must pass the browser preview before it can be saved). > **Note.** The module uses **one placement mode for the whole site**: in **Bubble** or **Attach** it adds the widget to every non-admin page; in **Inline** only the **Achla AI Search** block loads it, so pages without the block get no widget at all (no floating button). The block outputs nothing unless the placement is **Inline**. Like the WordPress plugin, it loads the widget through its own loader, not a `/w.js` tag. ### Single-page apps (React, Next.js, Vue …) - Add the tag once, in the root HTML document/layout, so it is loaded once per full page load. The widget mounts once and has no JavaScript API for re-mounting. - **Bubble** works best: the button is appended to `` and survives client-side navigation as long as your app does not replace ``. - **Inline** needs `` present when the widget mounts (server-rendered HTML). If your router later removes or re-creates that element, the inline box disappears until the next full page load. - **Attach** binds to the input element that exists at mount time; if the app re-renders that input, the binding is lost. ## Verify the installation 1. The tag is in the served HTML (manual installs). Expect exactly one match: 2. The key is enabled — must contain `"enabled":true`: 3. In the browser, open the page with DevTools → Console: there must be no lines starting with `[ai-search]`. Any such line carries an `AISX-…` code — see [Troubleshooting](https://achlaai.com/en/docs/troubleshooting). 4. The widget is visible: the floating button (bubble), the inline box (inline), or a dropdown when you press Enter in your search field (attach). 5. Ask a test question about your site: the answer should cite sources from your pages. 6. Run the installation check (replace the URL with a page of your site): `curl -s "https://achlaai.com/api/install-check?url=https://YOUR-SITE.example"`. It downloads the page, finds the tag, checks the key and the placement, and returns `AISX-C3xx` findings with fixes as JSON — `AISX-C309` means the installation looks correct. The **Check installation** button in the dashboard runs the same check for your site. Step 1 — replace the URL with a page of your site. ```bash curl -s "https://YOUR-SITE.example" | grep -o ']*/w\.js[^>]*>' ``` Step 2 — replace the key. ```bash curl -s "https://achlaai.com/api/widget-config?key=YOUR_PUBLIC_KEY" ``` Step 4, in the browser console — a value above 0 means the widget has mounted. ```javascript document.querySelectorAll('.aisx-btn, .aisx-inline, .aisx-drop').length ``` ## Content-Security-Policy If your site sends a Content-Security-Policy header, it must allow the widget origin. The widget loads its script from that origin, requests its configuration and answers from the same origin, and injects its stylesheet as a `