Hello. I’m new to the community (and almost new to n8n). I’ve created a RAG chatbot to converse about documents ingested into a Qdrant database. During development, it works very well. However, when deployed on another machine (not the server hosting n8n), a blank page appears in the browser. This is because the “When chat message received” node, which acts as the Trigger, needs to load a series of CSS stylesheets hosted on the internet. Since it cannot access the internet, it displays a blank page.
Tools used: The model is qwen3:14b hosted on Ollama. The database is Qdrant installed in Docker, along with n8n also installed in Docker. The embedding model is nomic-embed-text:v1.5, also installed on Ollama.
Does anyone have any ideas on how to deploy this in an installation without internet access? Thanks.
welcome to the n8n community @LuisJavier
You may need to avoid n8n’s built-in chat UI for an offline deployment and instead create a small local frontend that calls an n8n Webhook workflow, because the “When chat message received” page currently depends on external assets that your offline machine cannot load.
Thanks for getting back to me so quickly.
I think your answer is spot on, and that’s what I feared: I’ll have to create a small local interface that calls the Workflow via webhook. The thing is, that interface will never be as good as the one provided by the “When a chat message is received” node. Also, I’ll need to keep in mind that I’m using a Simple Memory node to maintain the conversation history, and I think I’ll need to somehow specify the session ID. Well, anyway. Thank you very much for your help.
@LuisJavier You’re thinking about this exactly right! I can help with both points you raised.
1. Building a simple offline chat interface that calls your webhook
You don’t need anything fancy. A single HTML file with vanilla JS is enough and works fully offline once saved locally:
<!DOCTYPE html>
<html>
<head><title>Local Chatbot</title></head>
<body>
<div id="chat"></div>
<input id="msg" type="text" />
<button onclick="send()">Send</button>
<script>
const WEBHOOK = 'http://YOUR-N8N-IP:5678/webhook/your-endpoint';
const sessionId = 'user-' + Date.now(); // unique per browser session
async function send() {
const msg = document.getElementById('msg').value;
document.getElementById('chat').innerHTML += '<p><b>You:</b> ' + msg + '</p>';
const res = await fetch(WEBHOOK, {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({ message: msg, sessionId: sessionId })
});
const data = await res.json();
document.getElementById('chat').innerHTML += '<p><b>Bot:</b> ' + data.output + '</p>';
document.getElementById('msg').value = '';
}
</script>
</body>
</html>
2. Session ID for Simple Memory node
In your n8n workflow, the Simple Memory node uses a session ID to separate conversation threads. When you receive the webhook, just pass the sessionId field from the request body into the “Session ID” field of the Simple Memory node using an expression like {{ $json.body.sessionId }}.
This way, each browser session gets its own isolated conversation history, exactly like the built-in chat widget does automatically.
Hope this gets your offline RAG chatbot fully working! If this solves it, feel free to mark the reply that helped most as Solution.