For the curious and for technical teams: the path of a question, from your WordPress pages to the answer shown in the chat, and the choices that make it reliable, fast and respectful of data.
Three parts and an AI
- The WordPress plugin, in PHP. It shows the chat with a shortcode, tells DigiSeer about every post you publish and, with a key, sends it your pages’ content: text, categories, ACF fields and SEO data.
- The API, in TypeScript with Bun and Elysia, on a PostgreSQL database. It indexes your pages, finds the useful passages, has the answer written and counts tokens.
- The app, in Angular. It is the chat your visitors see, and the place where you set everything: texts, styles, statistics, users.
- Mistral AI, the French AI, called on its European endpoint: one model to capture the meaning of texts, another to write the answers.
A separate service,
for a lighter WordPress
The index on our API, not in your WordPress database
- Your hosting lacks the right tools. Meaning-based search needs a database that can compare vectors (PostgreSQL and pgvector), and full-text search that reduces words to their stem in several languages. WordPress hosting, with MySQL or MariaDB, has neither: it would have to be installed, tuned and monitored on every site.
- Your site does no work. Indexing a page means splitting it, computing its vectors and summarising it with the AI; answering means searching, then writing. All this computing happens on our servers, not on your hosting: your site keeps its speed.
- No AI key on your side. Calls to Mistral AI leave from our API. No secret key is stored in your WordPress: nothing to protect or renew.
- Nothing is lost. Your content stays in WordPress, which remains the source. The index is only a working copy: it can be rebuilt at any time with “Index all”. DigiSeer only reads your published, public content, never drafts or private content.
- Your data is protected. Hosted in France (Scaleway), answers written by Mistral AI in the European Union, visitors’ IP addresses never stored in clear: the details are in Protecting data. If you uninstall the plugin, your site’s data is deleted 60 days later.
- The trade-off. The chat needs our service. If it is briefly unavailable, the chat shows a fallback message; your site itself is not affected.
An app, not a heavy plugin
- A light plugin. The DigiSeer plugin is about 70 KB. It connects your site to DigiSeer, reports content changes, creates the search page, and that’s all.
- New features without updates. The chat and the admin interface are an app (Angular) served by app.digiseer.app and shown in your WordPress. Each new version reaches you the same day, with no plugin update to run and no risk of breaking your site.
- A light app. The whole app, chat and admin included, fits in a file of about 1 MB, the weight of a photo.
- Downloaded once, then cached. On the first visit, the browser downloads the app: it takes a moment to show. Its files carry a version fingerprint in their name and the browser keeps them for a year; on later visits it only rechecks a small entry page, and the app shows almost instantly. With each new version, only the changed files are downloaded, once.
- No clash with your theme. The app is isolated in a frame (see Showing the chat). In your site’s pages, the plugin only adds a few CSS rules, all on classes prefixed
dsi-(button, full-screen window): they only touch your theme while the chat is open full screen, to sit above its header. In the app, each component has its own styles, isolated by Angular, on classes prefixedds_. - Less code on your side, fewer flaws. Most of the code runs on our servers, which we update and monitor ourselves.
1. Indexing your pages
When you publish, update or delete content, the plugin notifies the API at the end of the request, without slowing your site down. The API then reads the page through the plugin itself, with its categories, ACF fields and SEO data, even if the WordPress REST API is turned off.
- One text per page. For each page, the API builds a new text that brings together everything that describes it, in this order: its SEO data (title, meta description and focus keyphrase from Yoast SEO, Rank Math, All in One SEO, SEOPress or The SEO Framework, labelled in the page’s language), its content, its categories and taxonomies (“Categories: Help > Housing”), then its ACF fields. This is the text that is split, turned into vectors and indexed; the eye icon on the Indexing page shows it as is.
- Cleaning. HTML becomes text: scripts, styles and unprocessed shortcodes are removed. Tables keep each value tied to its row and column.
- Splitting. The text is cut into passages, sentence by sentence, with a small overlap so an idea is never cut in half.
- Meaning. Each passage, prefixed with the page title, is turned into a vector, a series of numbers that captures its meaning. Two texts that say the same thing have close vectors, even with different words.
- Words. PostgreSQL also indexes the text word by word, in the page’s language, with more weight on the title and keywords. In seven languages, words are reduced to their stem (“prices” finds “price”, “indexing” finds “indexed”); in the others, exact words are used, and meaning-based search takes over.
- Summary. A Mistral AI model writes a short summary and five keywords per page: these are the keywords offered under answers to keep the conversation going.
An unchanged page is not processed again: no tokens used. And the old index stays in place until the new one is complete.
2. Finding the right passages
For each question, two searches run in parallel: by meaning (distance between vectors, with pgvector) and by words (PostgreSQL full-text search). Their results are merged: a passage close in meaning that also contains the question’s words comes first.
- Relevance threshold. Passages too far from the question are left out. The threshold was calibrated on real questions, useful and off-topic, and you can make it looser or stricter.
- Several pages rather than one. Results show one line per page, and the answer draws on several pages rather than five pieces of the same one; only the page closest to the question can add a second passage.
- Follow-up questions. “And the prices?” is rewritten as a full question from the last exchanges, kept in the visitor’s browser and not on our servers.
- Typos. If nothing is found for a short question, its words are matched against your site’s vocabulary, and the chat shows “Results for…”.
- Several languages. A question asked in another language than your pages is translated by the AI into two wordings, with different words (price, rate, cost…); both are searched and each page keeps its best score. Pages in the chat’s language come first, then the others; a page’s translation is preferred to the original when there is one.
- Price questions. “How much does it cost?” is also searched with the words of pricing pages (price, pricing, plans), with no AI call: “cost” or “how much” are rarely the page’s own words.
3. Writing the answer
The four passages closest to the question, from three pages at most, and a second passage from the closest page are given to a Mistral AI model with strict instructions: answer only from these passages, in the visitor’s language, and make nothing up. If the passages are not enough, the chat says so, and the question joins the list of unanswered questions in your dashboard.
- Safe links. The AI cannot make up an address: every link in the answer points to a page on your site.
- As it is written. The answer shows while it is being written, without waiting for the end.
- Your settings. Length (five levels), tone (six), formal or informal address and your own instructions are added to DigiSeer’s rules, which always come first.
- No AI for nothing. Meaningless input, or a question with no passage close enough, never calls the model.
The tokens billed are those Mistral counts for each answer. The cost of rewriting a follow-up question travels in a ticket signed by the API: the browser cannot change it.
4. Showing the chat
The [DigiSeer] shortcode puts the chat in an iframe: it depends neither on your theme nor on your other plugins, and your page stays light. The iframe and the page exchange short messages (postMessage) for the chat’s height, scrolling while the answer is written, back to top and full screen. Every message is checked: it must come from the right window and the right origin.
No cookie is set on your visitors’ devices; the conversation history stays in their browser.
5. Protecting data
- IP addresses. Never stored in clear: only a fingerprint (HMAC-SHA256) specific to each site and each month is kept, so a visitor cannot be followed from one site to another or from one month to the next. It is deleted after 13 months.
- Questions. E-mails, phone numbers and long runs of digits (IBAN, card, social security) are masked before they are stored.
- Keys. The key linking your site to DigiSeer is random (256 bits) and compared in constant time.
- Reading your site. The API only reads public http(s) addresses, checks every redirect and refuses internal addresses (protection against SSRF attacks).
- Abuse. Requests are limited per address and per minute, and the number of questions per visitor and per day is set in the app.
- Isolation. A site’s chat can only read that site’s documents.
Where the data is and how long it is kept: see Security and privacy.
6. Reliability: how we work
An assistant that answers your visitors must stay accurate and available. Here are the rules we apply to every change.
DigiSeer in figures
- More than 300 automated tests, run before every release.
- 27 languages understood by the chat.
- Complete documentation: more than 30 sections, in French and English.
- Nightly backups, encrypted, with a restore test every month.
- Server monitoring every 5 minutes.
Writing the code
- Version control. All the code (API, app, plugin, website) lives in a private Git repository: every change is described, reviewed and reversible.
- Strict typing. API and app in strict TypeScript: a type error is caught at build time, before it reaches you.
- Versioned database. Every schema change is a numbered migration, written to add without breaking what exists.
- Code review. Full reviews, security first: access rights, request limits, personal data.
Testing
- Nearly 300 automated tests. Search, links in answers, languages, access rights, privacy, billing, outages of external services.
- Test database. Every change is tried locally, on a copy of production, with Stripe payments in test mode.
- Fictitious data. Screenshots, demos and tests use a fictitious account, never our customers’ data.
Updating
- No downtime. The API is updated without interrupting your visitors’ chat.
- Rollback. Every update is reviewed before it is applied and can be rolled back; a restorable copy of the code precedes every change.
- Visible version. A version number, at the bottom of the admin area and attached to your support requests.
Running
- Containers. The API runs in a Docker container (official Bun image, production dependencies only): the same environment at every update.
- Automatic restart. PM2 restarts the API if it stops; Docker restarts the container, even after a server reboot.
- Health check. Every 30 seconds, Docker checks that the API answers.
- Logs, secrets, network. Logs outside the container (30 days), keys and passwords outside the code, services linked by a private network.
Monitoring
- Every 5 minutes. Memory, disk, processor, API and website responses; a full health report reaches us every morning.
- External monitoring. An alert goes out even if the whole server stops.
- Degraded, never silent. If the AI, emails, payments or sign-in stop responding, the app says so, and the chat offers the pages that match the question.
Protecting and improving
- Backups. Encrypted every night, stored off the server, in France; test restores check that they can be used.
- Continuous improvement. Unanswered questions and your visitors’ 👍 / 👎 feedback show us what to improve; new features are announced in the app.
The tech stack
| Role | Choice |
|---|---|
| WordPress plugin | PHP, no dependencies |
| API | TypeScript, Bun, Elysia |
| Database | PostgreSQL, pgvector, full-text search, Drizzle ORM |
| App and chat | Angular |
| AI | Mistral AI models, European endpoint |
| Page language | franc, local detection, no AI call |
| Hosting | Scaleway, France |
| Payment | Stripe |
Open source tools we love
DigiSeer is built on free software. These are the ones we recommend without hesitation:
- PostgreSQL and pgvector. One database for data, full-text search and search by meaning: no separate search engine to maintain.
- Bun. Instant startup, TypeScript with no build step, and a built-in test runner.
- Elysia. A fast web server, typed end to end: every piece of data entering the API is validated.
- Drizzle ORM. Typed, readable SQL queries, with no magic.
- Angular. Its signals keep the chat reactive without needless complexity.
- WordPress. Of course: its hooks make automatic indexing possible.
- franc. It recognises the language of a text locally, with no AI call.
- marked and pdf-lib. One formats the documentation, the other produces usage statements as PDF.
- Puppeteer. The documentation screenshots are retaken automatically, with the demo account.
Thanks to their authors and contributors.
A technical question? Write to us.