One shortcode. Full brand control. Streams AI-powered domain suggestions directly into any page — API key stays server-side, results sorted by relevance, basket connected.
[ai_domain_search]
— paste on any page or post
ai-domain-search/ to /wp-content/plugins/ and activate.[ai_domain_search] to any page or post. Done.Three PHP classes, no external dependencies. The plugin proxies all AI calls server-side — the API key never touches the browser.
aisdsConfig JS object with all settings. CSS custom properties written inline from saved values — correct before JS runs.The proxy streams the AI service response straight through to the browser. No buffering. First result appears in ~4 seconds.
User types a business description — the widget sends it to the AI service and streams results back via Server-Sent Events. Domains appear one by one as they resolve. First result in ~4 seconds, not after the full search completes.
SSE delivers domains in CNR batch-arrival order (random). When the stream ends, results are re-sorted client-side so the best match is always at the top. See scoring rules below.
Brand colour pickers (primary, accent, text, background) output as CSS custom properties. Five card border presets: Flat, Soft, Medium, Rounded, Shadow. Custom CSS textarea for complete override control. Live preview updates in real time before saving.
Choose 1, 2, 3, or 4 columns. Set a max-results cap — the plugin snaps it to the nearest multiple of your column count so you never get orphaned half-rows. Premium domain badge shows registry price inline.
When enabled, domains with a discounted TLD price get a coloured outline and a pill badge (e.g. "Sale"). Detects discounts from the basket API TLD price map automatically — no manual tagging.
Language setting controls price period strings (/yr → /år → Jahr) and all customer-facing labels. Every widget text label is also individually overridable in settings.
Domains stream in random CNR batch-arrival order. When the stream ends the widget re-sorts all results client-side using this scoring formula.
| Signal | Points |
|---|---|
| Query word (≥3 chars) found in domain name | word.length × 4 per word |
| 2 or more query words matched (compound bonus) | +15 |
| Matched characters ÷ name length (efficiency — rewards tight exact matches) | up to +10 |
| TLD matches locale preference (.no → no, .fi → fi, .de → de, .com → en) | +5 |
Query words are lowercased, non-alphanumeric stripped, and words shorter than 3 characters dropped before scoring. Only the domain name part (before the first .) is scored against.
onkel edvins bodega — locale: noEach search increments an internal generation counter. Events queued from a previous EventSource are silently discarded if the counter has advanced — domains from an old search can never bleed into new results.
Choose one action per widget. Configure in Settings → AI Domain Search → Button action.
Redirect to a URL template when the button is clicked. Use {{domain}} as a placeholder for the selected domain name.
Adds a configurable product to the WooCommerce cart with the selected domain name attached as order metadata. WooCommerce must be active. The cart fragment is refreshed automatically after adding.
Dispatches a custom DOM event on document for your theme or app to handle — no redirect, no WooCommerce dependency.
Resolves the TLD plan UUID from the price map, builds a full basket payload (merging any previously added items from the client-side cache), and POSTs to your configured basket endpoint. On success redirects to the cart page.
x-tenant / x-brand headers sent on all basket API calls| Setting | |
|---|---|
| API | |
| Service URL | |
| API Key | |
| Styling | |
| Primary colour | |
| Accent colour | |
| Text colour | |
| Background colour | |
| Card border style | |
| Custom CSS | |
| Layout | |
| Columns | |
| Max results | |
| Campaign highlight | |
| Language & text | |
| Language | |
| Search label | |
| Placeholder | |
| Button label | |
| Added state label | |
| Basket API (GravityVault / Uniweb) | |
| Shop base URL | |
| TLD list path | |
| Basket path | |
| Cart redirect URL | |
| Market region ID | |
| Tenant slug | |
The Bearer token is stored in WordPress options and injected by the PHP proxy. It never appears in page source, JS, or network requests from the browser.
WP transient-based per-IP counter on the SSE proxy. Returns HTTP 429 when exceeded. Prevents abuse without requiring a session or login.
Query validated: minimum 2 chars, maximum 500. Nonce checked on every AJAX action. Basket payload whitelisted field-by-field before forwarding.
Server-side WP transient cache on the TLD list endpoint. Client-side localStorage cache with 1-hour TTL. TLD data rarely changes intra-day — no repeated fetches.
Added items cached client-side for the page session. Eliminates the GET round-trip on subsequent adds — the browser sends existing items directly, cutting one HTTP call from the critical path.
Proxy checks for curl_init before opening the stream. If cURL is missing it emits a structured SSE error event rather than a PHP fatal error.