Here How to Build a Chatbot for Free Using OpenRouter and DeepSeek APIs

I wanted to upload here, but video transcoding was in progress for about 10 days. I deleted and uploaded again, but the same issue happened. So I uploaded the video on YouTube for you to see how the chatbot is working. Note that this is just a frontend app using vanilla technologies, HTML, CSS, and, JavaScript. I have provided the complete code below, all you need to do is create your API key from OpenRouter, and paste in the code: const API_KEY = "Add your API KEY"; const MODEL = "deepseek/deepseek-r1:free"; Here is the complete code for your personal use: Now let's go through with the functionalities I have added in this chatbot. 1. Chat Messaging and API Integration User Message Handling When a user types and sends a message, it’s immediately added to the conversation. The code appends the message to the chat history and displays it on the screen. // Add a user message to the chat and save it addMessageToUI("user", message); chatHistory[currentChatId].messages.push({ role: "user", content: message, }); API Call to OpenRouter The chatbot uses the OpenRouter API with the free model (deepseek/deepseek-r1:free) to get chat completions. A POST request is made with the conversation history, and the response is streamed back. fetch("https://openrouter.ai/api/v1/chat/completions", { method: "POST", headers: { Authorization: `Bearer ${API_KEY}`, "Content-Type": "application/json", }, body: JSON.stringify({ model: "deepseek/deepseek-r1:free", messages: chatHistory[currentChatId].messages, stream: true, }), }); 2. Streaming Responses and Typing Effects Incremental Response Display The API response is streamed, meaning the assistant’s reply is received and displayed letter-by-letter. This simulates a real-time typing effect, making the conversation feel interactive. function processBuffer() { if (typingBuffer.length > 0 && !stopGeneration) { accumulatedText += typingBuffer[0]; typingBuffer = typingBuffer.slice(1); messageContent.innerHTML = getStableRendering(accumulatedText); setTimeout(processBuffer, typingSpeed); } } Stop Generation Option A stop button allows users to halt the ongoing streaming process if they wish to interrupt the assistant’s reply. 3. Markdown Processing and Code Highlighting Markdown Rendering Incoming text is processed using the Marked.js library. This converts markdown (including headers, lists, and links) into HTML for proper display. function processMarkdownContent(content) { return marked.parse(content); } Code Block Detection and Syntax Highlighting The chatbot detects code blocks (demarcated by triple backticks) and renders them separately. It uses Highlight.js to apply syntax highlighting and even adds a copy-to-clipboard button. // Code snippet for copy-to-clipboard on code blocks copyButton.addEventListener("click", () => { navigator.clipboard.writeText(segment.content).then(() => { // Feedback on successful copy }); }); 4. File Upload and Processing File Upload Users can upload files (images, text files, JSON, etc.). The file is read using the FileReader API and a preview is shown before it is sent as part of the conversation. fileUploadInput.addEventListener("change", (event) => { const file = event.target.files[0]; if (file) { pendingFile = file; displayPendingFilePreview(file); } }); File Content Handling Once a file is selected, its content is read (as a data URL for images or text for documents) and then integrated into the chat as a user message. 5. Chat History and Session Management Local Storage of Chats Each chat session is stored in the browser’s localStorage, allowing the conversation history to persist between sessions. New chats can be created, and old chats can be reloaded or cleared. // Saving chat history to localStorage localStorage.setItem("chatHistory", JSON.stringify(chatHistory)); Multiple Sessions The chat history sidebar lets users switch between multiple conversations, delete or rename sessions, ensuring smooth session management. 6. Chat Export, Regeneration, and Options Exporting Conversations Users can export the current chat conversation as a Markdown file. The conversation (with messages from both the user and the assistant) is compiled into a text blob and downloaded. const blob = new Blob([exportText], { type: "text/markdown" }); a.download = `${chat.title.replace(/[^\w\s]/gi, "")}.md`; Regenerate Response If the assistant’s last response isn’t satisfactory, the “regenerate response” functionality removes it and makes a new API call to get an updated reply. Chat Options Each chat history item comes with options (delete or rename) managed

Mar 20, 2025 - 08:24
 0
Here How to Build a Chatbot for Free Using OpenRouter and DeepSeek APIs

I wanted to upload here, but video transcoding was in progress for about 10 days. I deleted and uploaded again, but the same issue happened.

So I uploaded the video on YouTube for you to see how the chatbot is working.

Note that this is just a frontend app using vanilla technologies, HTML, CSS, and, JavaScript.

I have provided the complete code below, all you need to do is create your API key from OpenRouter, and paste in the code:

const API_KEY =
          "Add your API KEY";
        const MODEL = "deepseek/deepseek-r1:free";

Image description

Here is the complete code for your personal use:

Now let's go through with the functionalities I have added in this chatbot.

1. Chat Messaging and API Integration

User Message Handling

When a user types and sends a message, it’s immediately added to the conversation. The code appends the message to the chat history and displays it on the screen.

// Add a user message to the chat and save it
addMessageToUI("user", message);
chatHistory[currentChatId].messages.push({
  role: "user",
  content: message,
});

API Call to OpenRouter

The chatbot uses the OpenRouter API with the free model (deepseek/deepseek-r1:free) to get chat completions. A POST request is made with the conversation history, and the response is streamed back.

fetch("https://openrouter.ai/api/v1/chat/completions", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    model: "deepseek/deepseek-r1:free",
    messages: chatHistory[currentChatId].messages,
    stream: true,
  }),
});

2. Streaming Responses and Typing Effects

Incremental Response Display

The API response is streamed, meaning the assistant’s reply is received and displayed letter-by-letter. This simulates a real-time typing effect, making the conversation feel interactive.

function processBuffer() {
  if (typingBuffer.length > 0 && !stopGeneration) {
    accumulatedText += typingBuffer[0];
    typingBuffer = typingBuffer.slice(1);
    messageContent.innerHTML = getStableRendering(accumulatedText);
    setTimeout(processBuffer, typingSpeed);
  }
}

Stop Generation Option

A stop button allows users to halt the ongoing streaming process if they wish to interrupt the assistant’s reply.

3. Markdown Processing and Code Highlighting

Markdown Rendering

Incoming text is processed using the Marked.js library. This converts markdown (including headers, lists, and links) into HTML for proper display.

function processMarkdownContent(content) {
  return marked.parse(content);
}

Code Block Detection and Syntax Highlighting

The chatbot detects code blocks (demarcated by triple backticks) and renders them separately. It uses Highlight.js to apply syntax highlighting and even adds a copy-to-clipboard button.

// Code snippet for copy-to-clipboard on code blocks
copyButton.addEventListener("click", () => {
  navigator.clipboard.writeText(segment.content).then(() => {
    // Feedback on successful copy
  });
});

4. File Upload and Processing

File Upload

Users can upload files (images, text files, JSON, etc.). The file is read using the FileReader API and a preview is shown before it is sent as part of the conversation.

fileUploadInput.addEventListener("change", (event) => {
  const file = event.target.files[0];
  if (file) {
    pendingFile = file;
    displayPendingFilePreview(file);
  }
});

File Content Handling

Once a file is selected, its content is read (as a data URL for images or text for documents) and then integrated into the chat as a user message.

5. Chat History and Session Management

Local Storage of Chats

Each chat session is stored in the browser’s localStorage, allowing the conversation history to persist between sessions. New chats can be created, and old chats can be reloaded or cleared.

// Saving chat history to localStorage
localStorage.setItem("chatHistory", JSON.stringify(chatHistory));

Multiple Sessions

The chat history sidebar lets users switch between multiple conversations, delete or rename sessions, ensuring smooth session management.

6. Chat Export, Regeneration, and Options

Exporting Conversations

Users can export the current chat conversation as a Markdown file. The conversation (with messages from both the user and the assistant) is compiled into a text blob and downloaded.

const blob = new Blob([exportText], { type: "text/markdown" });
a.download = `${chat.title.replace(/[^\w\s]/gi, "")}.md`;

Regenerate Response

If the assistant’s last response isn’t satisfactory, the “regenerate response” functionality removes it and makes a new API call to get an updated reply.

Chat Options

Each chat history item comes with options (delete or rename) managed via a drop-down menu.

7. Additional Functionalities

Theme Toggling

Users can switch between light and dark modes. The selected theme is stored in localStorage, and the page’s class list is updated accordingly.

Auto-resizing Input

The textarea for user input automatically adjusts its height based on the amount of text, improving usability.

function autoResizeTextarea() {
  userInput.style.height = "auto";
  userInput.style.height = userInput.scrollHeight + "px";
}

8. Third Party Libraries and Services

  • OpenRouter API:

    Used for generating chat completions via the deepseek/deepseek-r1:free model.

  • Marked.js: A Markdown parser that converts Markdown text into HTML.

  • Highlight.js: Provides syntax highlighting for code blocks within the conversation.

  • Font Awesome: Supplies icons used throughout the interface (e.g., for buttons and options).

  • CDN Services: Libraries such as Marked.js, Highlight.js, and Font Awesome are loaded via CDN (e.g., from cdnjs).

What would you like to add more in this chatbot? I have provided you the code, try enhancing and adding more functionalities.

Keep supporting, keep sharing, and let’s grow together!