Migration guide · Open WebUI
Keep Open WebUI's Google PSE web search working after the shutdown
Open WebUI's google_pse web search engine calls the Custom Search JSON API, which Google discontinues on January 1, 2027. Its key and engine ID are settings, but its URL is written in its code. Change that one line, mount the file into your container, and put your Searlo key in the Google PSE API Key field.
Where Open WebUI keeps the URL and key
Admin Panel, Settings, Web Search holds the engine (google_pse), the Google PSE API Key and the Google PSE Engine Id. Open WebUI runs the engine only when both of those are filled in.
The address is not a setting: search_google_pse() in backend/open_webui/retrieval/web/google_pse.py sets it to https://www.googleapis.com/customsearch/v1 and sends cx, q, key, num and start, fetching pages of 10 when you ask for more than 10 results. Every one of those parameters works on Searlo's drop-in, and the function reads link, title and snippet from items, which Searlo returns.
The change
One line in Open WebUI's code, as of v0.12.4. Nothing else in the file changes.
backend/open_webui/retrieval/web/google_pse.py
- url = 'https://www.googleapis.com/customsearch/v1'
+ url = 'https://api.searlo.tech/customsearch/v1'Switch in four steps
- 01Copy the engine out and change its URLCopy google_pse.py from your running container and replace Google's URL with Searlo's, as in the shell commands below.
- 02Mount the changed fileMount it over /app/backend/open_webui/retrieval/web/google_pse.py with a docker-compose.override.yaml or one extra -v flag, then recreate the container.
- 03Enter your Searlo keyAdmin Panel, Settings, Web Search: Web Search Engine google_pse, Google PSE API Key your Searlo API key. Google PSE Engine Id must not be empty; keep your cx or enter any short text, Searlo ignores it. Save.
- 04Check itIn a chat, turn on web search, ask something current, and check that the answer lists sources. Each search shows in your Searlo dashboard.
Copy and change the file
Run these where you run Docker. The container is named open-webui in Open WebUI's own compose file and README; use your name if it differs.
# Copy the Google PSE engine out of your running container (named open-webui here)
docker cp open-webui:/app/backend/open_webui/retrieval/web/google_pse.py ./google_pse.py
# Point it at Searlo: one URL changes (on macOS: sed -i '' ...)
sed -i 's#https://www.googleapis.com/customsearch/v1#https://api.searlo.tech/customsearch/v1#' google_pse.py
grep -n "url = " google_pse.py
# url = 'https://api.searlo.tech/customsearch/v1'
Mount it
With Docker Compose, an override file next to Open WebUI's docker-compose.yaml adds the mount, then docker compose up -d recreates the container. With docker run, add the -v flag to the command you already use.
docker-compose.override.yaml (next to Open WebUI's docker-compose.yaml)
services:
open-webui:
volumes:
# The patched engine, mounted over the one in the image
- ./google_pse.py:/app/backend/open_webui/retrieval/web/google_pse.py:ro
# Add one -v flag to the docker run command you already use, for example:
docker run -d -p 3000:8080 \
-v open-webui:/app/backend/data \
-v "$(pwd)/google_pse.py:/app/backend/open_webui/retrieval/web/google_pse.py:ro" \
--name open-webui --restart always ghcr.io/open-webui/open-webui:main
Notes
Each search is 1 credit, and a failed search is not charged. Open WebUI searches every query it generates for a message, and each one counts; a result count above 10 also takes one call per 10 results.
Results come from the whole web, which is what chat web search usually wants. An engine you limited to a few sites in Google's console does not carry over, because cx has no effect on Searlo.
Before you upgrade Open WebUI, remove the mount, upgrade, then copy the new google_pse.py and change it again. A mounted file from an older version would hide changes the new version makes to it.
The Google PSE settings are persistent: after the first start Open WebUI keeps its own copy, so set the key in the Admin Panel rather than only in GOOGLE_PSE_API_KEY.
What we ran on 2026-10-25: Open WebUI v0.12.4's search_google_pse(), with the sed change, against a server built from the drop-in's own code, for 3 and 15 results. The file path comes from Open WebUI's Dockerfile; we did not run an Open WebUI container for this guide.
FAQ
Questions
Can I set the Google PSE URL in Open WebUI's settings?
No, not as of v0.12.4. The key and the engine ID are settings; the URL is written in google_pse.py.
Why not use Open WebUI's external web search engine?
It sends a POST with a JSON body to the URL you give it and expects a list back. Searlo's drop-in answers Google's GET request instead, so the google_pse engine is the one that fits without new code.
Search the web from Open WebUI
Create a key, change one line, mount the file.