========================================================================
JavaScript Search App Tutorial: Building a Simple Document Search Engine
========================================================================
This tutorial will guide you through building a simple web-based document search engine using the LocalVectorDB server API. You'll create a single-page application that can search through documents using vector similarity, keyword search, or hybrid search - all without writing any Python code!
What We'll Build
================
We'll create a clean, responsive web application that:
* Connects to a LocalVectorDB server via REST API
* Provides a search interface with different search types
* Displays search results with relevance scores
* Shows document metadata and content previews
* Includes basic error handling and loading states
No Python knowledge required - just HTML, CSS, and JavaScript!
Prerequisites
=============
Before starting, ensure you have:
* Python 3.12 or higher
* A web browser (Chrome, Firefox, Safari, etc.)
* Basic knowledge of HTML, CSS, and JavaScript
* A text editor or IDE
Setting Up the Server
=====================
First, let's set up and start the LocalVectorDB server using the command-line interface.
Install and Configure LocalVectorDB
------------------------------------
.. code-block:: bash
# Install LocalVectorDB (requires Python 3.12+)
pip install localvectordb
# Create a basic configuration file
lvdb config init --interactive
During the interactive setup, choose these options:
* **Configuration file path**: `./.lvdb-config.toml` (default)
* **Server host**: `127.0.0.1`
* **Server port**: `8000`
* **Database directory**: `./search-demo-db`
* **Enable CORS**: `Yes` (important for web applications!)
* **CORS origins**: `localhost` or `all` (for development **only**)
* **API Authentication**: `No` (to keep it simple)
Create Sample Documents and Database
------------------------------------
Let's create some sample documents to search through. First, create a folder for our documents:
.. code-block:: bash
# Create a folder for sample documents
mkdir server-docs
# Copy some files that you'd like to search
cp /path/to/file server-docs/file
# ...etc.
Now create the database and add all the documents:
.. code-block:: bash
# Create a new database for our demo
lvdb create search_demo
# Add all documents from the server-docs folder
# NOTE: only plaintext files can be added from the cli this way. You must convert PDFs or DOCX files first.
lvdb db search_demo add "server-docs/*.txt"
Start the Server
----------------
.. code-block:: bash
# Start the LocalVectorDB server
lvdb serve
You should see output indicating the server is running on `http://127.0.0.1:8000`. Keep this terminal window open while developing the web application.
Creating the Web Application
============================
Now let's build our single-page search application. We'll create three files: HTML for structure, CSS for styling, and JavaScript for functionality.
HTML Structure (index.html)
----------------------------
.. code-block:: html
LocalVectorDB Search Demo
Document Search Engine
Powered by LocalVectorDB
Search Results
No results found
Try adjusting your search terms or using a different search type.
Something went wrong
Please check if the LocalVectorDB server is running.
`;
return card;
}
/**
* Set searching state
*/
function setSearchingState(searching) {
isSearching = searching;
if (searching) {
searchButton.classList.add('searching');
searchButton.disabled = true;
searchInput.disabled = true;
} else {
searchButton.classList.remove('searching');
searchButton.disabled = false;
searchInput.disabled = false;
}
}
/**
* Hide all result states
*/
function hideAllStates() {
resultsHeader.classList.add('hidden');
noResults.classList.add('hidden');
errorMessage.classList.add('hidden');
resultsContainer.innerHTML = '';
}
/**
* Show no results state
*/
function showNoResults() {
hideAllStates();
noResults.classList.remove('hidden');
}
/**
* Show error state
*/
function showError(message) {
hideAllStates();
errorText.textContent = message;
errorMessage.classList.remove('hidden');
}
/**
* Escape HTML to prevent XSS
*/
function escapeHtml(text) {
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
/**
* Utility function to format numbers
*/
function formatNumber(num) {
return new Intl.NumberFormat().format(num);
}
/**
* Add some helpful keyboard shortcuts
*/
document.addEventListener('keydown', function(event) {
// Focus search input when pressing '/' key
if (event.key === '/' && event.target !== searchInput) {
event.preventDefault();
searchInput.focus();
searchInput.select();
}
// Clear search when pressing Escape
if (event.key === 'Escape') {
if (document.activeElement === searchInput) {
searchInput.value = '';
hideAllStates();
} else {
searchInput.focus();
}
}
});
// Add some helpful console commands for development
if (typeof window !== 'undefined') {
window.searchDemo = {
search: performSearch,
checkConnection: checkServerConnection,
config: {
apiUrl: API_BASE_URL,
database: DATABASE_NAME
}
};
console.log('Development tools available at window.searchDemo');
}
Running the Application
=======================
Now let's put it all together and run our search application:
Create the Project Structure
----------------------------
Create your web application files in the same directory where you have your configuration:
.. code-block:: bash
# You should already be in your main project directory
# Create the web application files
touch index.html styles.css script.js
Add the code from the sections above to each respective file.
Start the LocalVectorDB Server
------------------------------
The LocalVectorDB server is a FastAPI application that exposes the REST API under
``/api/v1`` -- it does **not** serve your static HTML/CSS/JS files. We'll run the API server
here and load the front-end files separately in the next step.
.. code-block:: bash
# Start the LocalVectorDB server (serves the API only)
lvdb serve
You should see output indicating the server is running on `http://127.0.0.1:8000`.
Access Your Search Engine
-------------------------
Because the LocalVectorDB server only serves the API (not static files), open the front-end
yourself. You have two easy options:
**Option A -- open the file directly**
Just double-click ``index.html`` (or drag it into your browser). It will load from a
``file://`` URL and call the API at ``http://127.0.0.1:8000``. This is a cross-origin request,
which is exactly why we enabled CORS during configuration -- without it the browser would
block the requests.
**Option B -- run a tiny static file server**
Serve the three files over HTTP from their directory using Python's built-in server:
.. code-block:: bash
# In the directory containing index.html, styles.css, script.js
python -m http.server 8080
Then:
1. Make sure your LocalVectorDB API server is running on port 8000 (``lvdb serve``).
2. Open your browser and navigate to ``http://127.0.0.1:8080/index.html``.
3. (Either option) The page calls the API at ``http://127.0.0.1:8000/api/v1`` -- keep that
server running too.
You should see your search engine! Try searching for terms like:
* "programming language"
* "machine learning"
* "web development"
* "artificial intelligence"
Testing Different Search Types
===============================
Your search engine supports three different search modes:
**Vector Similarity Search**
Uses AI embeddings to find semantically similar content. Great for finding documents with similar meaning even if they use different words.
**Keyword Search**
Traditional text search that looks for exact word matches. Fast and precise for finding specific terms.
**Hybrid Search**
Combines both vector and keyword search for the best of both worlds. Usually provides the most relevant results.
Try the same query with different search types to see how the results differ!
Adding More Documents
=====================
You can easily add more documents to your search engine using the CLI:
.. code-block:: bash
# Add a single document file
lvdb db search_demo add /path/to/your/document.txt
# Add multiple documents from a folder
lvdb db search_demo add "/path/to/documents/*.txt"
# Add documents with custom metadata
lvdb db search_demo add server-docs/new-doc.txt --metadata '{"category":"tutorial","author":"you"}'
# Add all files from your server-docs folder again (if you add more)
lvdb db search_demo add "server-docs/*.txt"
Troubleshooting
===============
**CORS Errors**
Make sure you enabled CORS when configuring the server. You can also add CORS headers manually:
.. code-block:: bash
lvdb config set server.security.cors_enabled true
lvdb config set server.security.cors_allowed_origins '["http://localhost:8080"]'
**Server Connection Failed**
Verify the LocalVectorDB server is running:
.. code-block:: bash
# Check if server is responding
curl http://127.0.0.1:8000/api/v1/health
**No Search Results**
Make sure you have documents in your database:
.. code-block:: bash
lvdb db search_demo list
**JavaScript Errors**
Open your browser's developer console (F12) to see detailed error messages.
Enhancing the Application
=========================
Here are some ideas to extend your search engine:
**Add Document Upload**
The server has two distinct endpoints for adding documents, and they take different payloads:
* ``POST /{db}/documents`` -- **JSON** body for text you already have in memory
(``{"documents": [...], "metadata": [...]}``).
* ``POST /{db}/upload`` -- **multipart/form-data** for uploading actual files; the server
extracts the text for you. File upload must be enabled on the server
(``lvdb config init --enable-file-upload`` / ``lvdb config set server.file_upload_enabled true``).
Upload a real file (multipart) to the ``/upload`` endpoint:
.. code-block:: javascript
// Wire this to an element, e.g. input.files[0]
function handleFileUpload(file) {
const formData = new FormData();
formData.append('files', file); // the server extracts text from the file
formData.append('metadata', JSON.stringify({
filename: file.name,
uploaded_at: new Date().toISOString()
}));
return fetch(`${API_BASE_URL}/${DATABASE_NAME}/upload`, {
method: 'POST',
body: formData // do NOT set Content-Type; the browser sets the multipart boundary
});
}
Or send raw text you already have as **JSON** to the ``/documents`` endpoint:
.. code-block:: javascript
function addText(text) {
return fetch(`${API_BASE_URL}/${DATABASE_NAME}/documents`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
documents: [text],
metadata: [{ uploaded_at: new Date().toISOString() }]
})
});
}
**Add Result Filtering**
.. code-block:: javascript
// Add metadata filters to your search
const searchParams = {
query: query,
search_type: searchType.value,
filters: {
category: selectedCategory,
author: selectedAuthor
}
};
**Add Search History**
.. code-block:: javascript
// Store searches in localStorage
function saveSearchHistory(query, resultCount) {
const history = JSON.parse(localStorage.getItem('searchHistory') || '[]');
history.unshift({ query, resultCount, timestamp: Date.now() });
localStorage.setItem('searchHistory', JSON.stringify(history.slice(0, 10)));
}
**Add Real-time Search**
.. code-block:: javascript
// Debounced search as user types
let searchTimeout;
searchInput.addEventListener('input', function() {
clearTimeout(searchTimeout);
searchTimeout = setTimeout(() => {
if (searchInput.value.length > 2) {
performSearch(searchInput.value);
}
}, 500);
});
Deployment Options
==================
**Static Hosting**
Deploy your search engine to GitHub Pages, Netlify, or Vercel. Just make sure to update the API URL to point to your deployed server.
**Docker Container**
Package both the server and web app in a Docker container for easy deployment.
**Cloud Deployment**
Deploy the LocalVectorDB server to cloud platforms like Railway, Render, or DigitalOcean.
Conclusion
==========
Congratulations! You've built a complete document search engine using LocalVectorDB and vanilla JavaScript. Your application demonstrates:
**Core Features**
- Vector similarity search with AI embeddings
- Multiple search types (vector, keyword, hybrid)
- Clean, responsive user interface
- Real-time search capabilities
- Error handling and loading states
**Technical Skills**
- REST API integration
- Modern JavaScript (async/await, fetch)
- Responsive CSS design
- DOM manipulation
- User experience best practices
**LocalVectorDB Integration**
- Server configuration and management
- Document ingestion via CLI
- RESTful API usage
- Search result processing
This foundation can be extended into more sophisticated applications like document management systems, knowledge bases,
or AI-powered search engines. The modular design makes it easy to add features like authentication, file uploads,
advanced filtering, and more.
Happy searching!