Skip to main content

Command Palette

Search for a command to run...

Weekend Dev Log: Building a Complete Search System from Scratch

Updated
โ€ข5 min read
Weekend Dev Log: Building a Complete Search System from Scratch

Posted on December 21, 2024 ยท 8 min read ยท #webdev #astro #javascript #search

๐ŸŽฏ The Challenge

This weekend, I set out to solve a critical problem for Txchyon: users needed a way to find content across our growing platform. With guides, documentation, and blog posts scattered across different directories, finding specific information was becoming a challenge.

Little did I know I was about to embark on a 3-day journey through Astro's architecture, JavaScript debugging, and search algorithm design. I also had to deal with the catergory and subcategory system on astro but that's in the next dev log.

๐Ÿ“Š The Goal

Build a complete search system that:

Searches across pages (src/pages/) and guides (guides/**/.md)

Provides real-time results as users type

Offers both client-side and server-side search options

Maintains excellent performance

Works seamlessly across all devices

๐Ÿ—๏ธ Day 1: Laying the Foundation The Architecture

I started by designing a dual-source data collection system: astro

const allPages = await Astro.glob('../.{md,astro}'); const allGuides = await Astro.glob('../../../guides/**/.md');

const searchList = [ ...allPages.map(page => ({ url: page.url, title: page.frontmatter.title, description: page.frontmatter.description, content: page.rawContent() })), ...allGuides.map(guide => ({ url: /guides/${guide.file.split('/').pop().replace('.md', '')}, title: guide.frontmatter.title, description: guide.frontmatter.description, content: guide.rawContent() }))

];

Initial Files Created:

/search.astro - Real-time search interface

/search-results.astro - Server-side results page

SearchBar.astro - Reusable component

Progress: Basic structure complete, but...

๐Ÿ› Day 2: The Debugging Marathon

This was the most intense part of the weekend. Four major bugs tried to derail the project: Bug #1: Uncaught SyntaxError: unexpected token: '{'

The Problem: Template literal escaping issues between Astro and JavaScript.

The Fix: astro

Bug #2: ReferenceError: pm is not defined

The Problem: Guide content processing was failing due to markdown parsing issues.

The Fix: Proper content extraction with fallbacks: javascript

const content = item.rawContent() || item.Content || '';

Bug #3: Path Resolution Chaos

Relative imports were breaking across different directory levels. Fixed by standardizing all import paths. Bug #4: Data Flow Breakdown

Ensuring proper serialization from Astro's server-side to client-side JavaScript required careful handling of async operations.

Progress: All critical bugs squashed, system stable!

๐ŸŽจ Day 3: Polishing & Performance

Real-time Search with Debouncing

Implemented 300ms debouncing to prevent performance issues: javascript

let debounceTimer; searchInput.addEventListener('input', (e) => { clearTimeout(debounceTimer); debounceTimer = setTimeout(() => { performSearch(e.target.value); }, 300); });

Smart Search Algorithm javascript

function performSearch(searchTerm, searchIndex) { return searchIndex.filter(item => { const searchFields = [ item.title?.toLowerCase() || '', item.description?.toLowerCase() || '',
item.content?.toLowerCase() || '' ];

return searchFields.some(field => field.includes(searchTerm.toLowerCase()) ); }); }

Keyboard Navigation

Added arrow key support for power users: javascript

document.addEventListener('keydown', (e) => { if (e.key === 'ArrowDown') { // Navigate down results } else if (e.key === 'ArrowUp') { // Navigate up results } else if (e.key === 'Enter') { // Select current result } });

๐Ÿ“ˆ Final Architecture text

txchyon/ โ”œโ”€โ”€ src/ โ”‚ โ”œโ”€โ”€ layouts/ โ”‚ โ”‚ โ””โ”€โ”€ Layout.astro โ”‚ โ”œโ”€โ”€ components/ โ”‚ โ”‚ โ””โ”€โ”€ SearchBar.astro # Reusable search component โ”‚ โ”œโ”€โ”€ pages/ โ”‚ โ”‚ โ”œโ”€โ”€ search.astro # Real-time search UI โ”‚ โ”‚ โ””โ”€โ”€ search-results.astro # Server-side results โ”‚ โ””โ”€โ”€ styles/ โ”‚ โ””โ”€โ”€ search.css โ”œโ”€โ”€ guides/ # External content โ”‚ โ”œโ”€โ”€ guide-1.md โ”‚ โ”œโ”€โ”€ guide-2.md โ”‚ โ””โ”€โ”€ ... โ””โ”€โ”€ package.json

๐ŸŽฏ What I finally Achieved

โœ… Core Features (100% Complete):

Real-time type-ahead search with instant feedback

Multi-source content search across pages and guides

Dual interface modes: SPA-like experience + server-side rendering

Smart result ranking (title matches > description > content)

URL parameter support (/search-results?q=term)

Mobile-responsive design that works flawlessly on all devices

Keyboard navigation for power users

โœ… Performance Metrics:

Search speed: < 10ms for typical queries

Initial load: < 50KB search data

Bundle size: Minimal JavaScript footprint

Memory usage: Efficient object reuse

โœ… User Experience:

Clean, modern interface with smooth animations

Helpful empty states and search tips

Click-outside-to-close behavior

Accessible color contrast and focus states

๐Ÿ† Key Learnings

Astro's Hybrid Architecture is powerful but requires careful data flow planning

Debugging template literals requires attention to escaping and serialization

Performance optimization is critical for real-time search (debouncing is your friend)

Mobile first design ensures accessibility for all users

Progressive enhancement (client-side + server-side options) provides the best UX

๐Ÿ”ฎ Future Enhancements (When Needed)

Search term highlighting in results

Synonyms & fuzzy matching ("js" finds "javascript")

Advanced filtering by content type or date

Search analytics dashboard to track popular queries

Voice search integration using Web Speech API

๐Ÿ“Š Weekend Stats

Lines of code: ~500

Components created: 3

Bugs fixed: 4 major, 6 minor

Test cases passed: 15/15

Coffee consumed: Let's not talk about it โ˜•

๐Ÿš€ The Result

What started as "we need search functionality" turned into a complete, production-ready search system that:

Enhances user experience with instant content discovery

Improves content accessibility across the entire platform

Maintains excellent performance even with growing content

Provides multiple access patterns for different user needs

The search is now live at txchyon.com/search and integrated throughout the platform, still have a little bit of adjustment but i'm super tired and sleepy so I'ma log off. At least it commit to git and pushed to cloudflare.

๐Ÿ’ญ Final Thoughts

This weekend reminded me why I love web development: starting with a problem, wrestling with technology, and emerging with a solution that genuinely helps users. The journey from "this should be simple" to "oh, that's why it's complex" to "aha, it works!" never gets old.

To fellow developers: Sometimes the most valuable feature isn't the flashiest one. A well-implemented search system might not get applause, but it'll be used dozens of times every day by people trying to find what they need and that's all that matters to me.

Now, time to actually use this search feature to find where I left my bag of twizzlers...

Want to see the code? The search components are open source as part of the Txchyon platform. Have questions about implementing search in your Astro project? Drop a comment on X best place to reach me.

Tags: #astro #webdev #search #javascript #tutorial #debugging #frontend