# Connect ChatGPT to a website: what actually has to move

> By Lawrence Dauchy, Founder, DFYe. Published 2026-08-10. 10 min read. Guides.
> Source: https://dfye.com/blog/connect-chatgpt-website/
> Language: en

The model knows nothing about your site until something hands it your pages. That handing over is the whole job, and it is smaller than it looks.

**TL;DR.** Connecting ChatGPT to a website means four things move: the visitor's question, the passages from your own pages that match it, any live store data the answer needs, and the answer itself with its source attached. The API key must never reach the browser, because anything in client-side JavaScript is readable and the bill is yours. Everything else is a choice between a plugin, a no-code connector, and a small server of your own.

Connecting ChatGPT to a website means four things move, and none of them is the model
itself. The visitor's question moves to code you control. The passages from your own
pages that match that question move alongside it. Any live store data the answer needs
moves in from your shop. Then the answer moves back with the page it came from
attached. The one hard rule is that **your API key must never reach the browser**,
because anything in client-side JavaScript is readable by anyone who opens developer
tools, and the bill for a leaked key is yours.

Everything else is a choice about who writes the middle piece.

## What does connecting actually mean?

It means putting something between your visitor and the model, because there is no
arrangement in which the two talk directly and you keep your key. That middle piece
does the same four jobs regardless of who builds it.

| Route | What you build | Best for | Main limit |
|---|---|---|---|
| A plugin | Nothing, you configure | Getting answering this week | The vendor's opinions about retrieval |
| A no-code connector | A flow in Zapier or Make | Teams already living in those tools | Latency, and per-task pricing at volume |
| Your own endpoint | A small server, a few hundred lines | Owning the decisions | You are now maintaining it |
| A hosted product | An account and a snippet | Non-developers | You hold neither the key nor the data |

The middle two rows are where most first attempts start and where most of them stall,
for the same reason: the first version is genuinely quick, and the distance between a
working demo and something you would let a customer touch is much longer than the
demo suggests.

## Why can the browser not call the API directly?

Because the key would be in the page, and a key in a page is a key in public.

This trips people up because the code looks so simple. A chat completion is one HTTP
POST with an Authorization header, the sort of thing
[fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch) does
in four lines, and it is tempting to put those four lines on the page and be done.
Anyone who opens developer tools then has your credential. People scan for these
automatically, and the first you hear about it is the invoice.

There is a second reason that stops the attempt even before the security one.
Browsers enforce [cross-origin rules](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS),
and an API that expects to be called from a server does not hand out permission to be
called from arbitrary pages. That is the guardrail working rather than an obstacle to
route around.

So the shape is fixed: browser talks to your endpoint, your endpoint talks to the
model. Your endpoint is also the only place where you can rate-limit an abusive
visitor, log what was asked, and stop a single scraper spending a month's budget in
an afternoon.

## How does it learn about your site?

By being handed the relevant part of your site with every question. Nothing else.

A model answers from what it was trained on. That does not include your delivery
windows, your current stock or your returns policy, and it may include a version of
your site scraped years ago, which is worse than nothing because it is confidently
out of date. Making it answer from your content is a two-step job.

First, index. Your pages are split into passages and each passage is converted into a
numeric representation, which is what
[embeddings](https://platform.openai.com/docs/guides/embeddings) are for. Store those
somewhere you can search.

Second, retrieve at question time. The visitor's question is converted the same way,
the closest passages come back, and those passages are sent to the model with an
instruction to answer from them and to say so when they do not contain the answer.

The part people skip is re-indexing. A passage built from a page you have since
edited is a quietly wrong answer waiting to happen, and a nightly rebuild means your
prices can be fourteen hours stale. Re-reading a page when it changes is the correct
behaviour and it is more work than it sounds, which is why plugins that do it well are
worth something.

## What has to move for a store question?

More than page content, and this is where the integration stops being generic.

| What moves | From where | Why it matters |
|---|---|---|
| The question | The widget, to your endpoint | Nothing works until you own this hop |
| Matched passages | Your index of published pages | The only reason the answer is about you |
| Order or stock data | Your store, at question time | Policy pages cannot answer "where is mine" |
| The answer and its source | Back to the widget | An answer you cannot check is a rumour |

Row three is the one that separates a chatbot that recites your shipping policy from
one that tells a customer where their parcel is. On WordPress that means the
[REST API](https://developer.wordpress.org/rest-api/), and on a shop it usually means
the [WooCommerce REST API](https://woocommerce.github.io/woocommerce-rest-api-docs/)
or the equivalent for your platform.

The safe way to wire it is not to hand the model your database. You expose a lookup in
your own code, describe it to the model, and let it ask for that lookup by name when a
question needs one. That is what
[function calling](https://platform.openai.com/docs/guides/function-calling) does, and
the indirection is the security boundary: your code decides whether to run the lookup,
which customer it is allowed to run for, and what comes back. A model that can request
an order status still cannot change one.

Which of these your site can support without a custom build is on
[works with](/works-with/), and the wiring itself is in [the docs](/docs/).

## What happens when it is slow or down?

Both will happen, and the answer you design for them is more visible to customers than
anything about model quality.

Slow first. A single answer is two round trips, not one: find the passages, then
generate from them. Cold, that can take several seconds, and a chat window showing
nothing for four seconds reads as broken. People close it and do not come back to find
out whether it worked.

The fix is to stream. Send the answer as it is produced so the first words appear
almost immediately, which turns a four-second wait into a four-second read. While
retrieval is still running, say what is happening rather than showing a bare spinner:
a line saying it is reading your pages is honest, sets the expectation, and is the
difference between waiting and abandoning.

Down second. Model providers have outages, your own host has outages, and a network
between them has more. Decide now what the widget says, because the default is a stack
trace or a silent failure and both are worse than an honest sentence. Something like
not being able to reach the answer service right now, with a link to your contact
page, costs nothing and keeps the customer inside your site. Your endpoint should fail
to a route, never to an error.

Two smaller things pay for themselves quickly. Put a timeout on the model call, so a
request that hangs fails fast into that same route rather than leaving somebody
watching a cursor. And cache the answers to identical questions, because the same four
questions arrive constantly. A cache turns your most common question into an instant
free answer and removes a whole class of variability from the experience.

None of this is exotic engineering. It is the difference between a demo and something
a customer meets on a bad day, and it is almost always the work that gets postponed.

## When should you not build this yourself?

When the plumbing is not the part of your week you want to spend, which is a
legitimate answer rather than an admission.

The first version really is an afternoon. An endpoint, an index over a few dozen
pages, a chat window. It will work, and it will feel like the job is nearly done. It
is not. What follows is the refusal behaviour, the exclusions for pages that must
never be quoted, re-indexing on edit, rate limiting, the widget itself, accessibility,
and the slow discovery that your delivery policy contradicts itself across three
pages. That is most of a month, and none of it is the interesting part.

Do not build it if you cannot own the key operationally either. Somebody has to notice
when spending changes shape, rotate the credential when a laptop is lost, and know
which environments hold a copy. A key nobody is responsible for is the most expensive
thing on this page.

And if your questions are mostly order status, consider whether a tracking link in the
confirmation email removes more of them than any of this. Solve that first and measure
what is left; what is left is a smaller and more interesting problem.

Set against that, building it yourself is the right call more often than the market
implies. You keep the key, you keep the data, you decide what the thing does when it
does not know, and you understand your own failure modes. If you are still deciding
what kind of product you want, [how to choose one](/blog/best-ai-chatbot-website/)
covers the shortlist, and
[what an AI chatbot for a website actually is](/blog/ai-chatbot-website/) covers the
category.

## Quick answers

### How do I connect ChatGPT to my website?

Through something that sits between the two, never directly. The visitor's question
goes to code you control, that code finds the passages from your pages that match it,
sends question and passages to the model, and returns the answer. The three ways to
get that middle piece are a plugin, a no-code connector like Zapier or Make, or a
small endpoint of your own. All three do the same four jobs.

### Can I call the OpenAI API from JavaScript in the browser?

Technically you can write the code, and you should not. Anything in client-side
JavaScript is readable by anyone who opens developer tools, including your API key,
and a key in the open gets found and used by strangers at your expense. The request
has to go through a server you control, which also gives you the only place to enforce
rate limits and log what happened.

### Does ChatGPT know what is on my website?

No, not unless something tells it. A model answers from what it was trained on, which
does not include your delivery windows, your stock or your returns policy, and may
include an outdated version of your site scraped years ago. Making it answer from your
content means indexing your pages and passing the matching passages along with the
question, every single time.

### How much does it cost to run?

Per token, on both what you send and what comes back, at a published price. Retrieval
raises the cost of the input because you are pasting passages into every request, so a
long answer with four source passages costs more than a one-line reply. For most small
sites this lands in the low tens of euros a month. Your own key means you pay the
provider directly, with nothing marked up.

### Can the chatbot look up a customer's order?

Yes, but not by giving the model access to your database. You expose a lookup in your
own code, tell the model that the lookup exists, and it asks for it by name when a
question needs it. Your code decides whether to run it and what to return. That
indirection is the security boundary, and it is the reason a bot can safely read order
status without being able to change one.

### Should I build this myself or install something?

Build it if the plumbing is the interesting part of your week and you want to own the
decisions. Install something if you want it answering by Friday. The honest middle
case is the one people miss: a first version takes an afternoon, and the ninety
percent that follows is refusal behaviour, exclusions, re-indexing and the widget,
which is most of a month.

## Sources

- [OpenAI: embeddings, the retrieval mechanism](https://platform.openai.com/docs/guides/embeddings)
- [OpenAI: function calling, how a model asks your code for a lookup](https://platform.openai.com/docs/guides/function-calling)
- [MDN: using the Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch)
- [MDN: cross-origin resource sharing](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS)
- [WordPress REST API handbook](https://developer.wordpress.org/rest-api/)
- [WooCommerce REST API documentation](https://woocommerce.github.io/woocommerce-rest-api-docs/)

---
*Published by [DFYe](https://dfye.com/). Free to read, index, quote and cite with attribution and a link.*
