Building jargons.dev [# The Dictionary Search Engine
What is a Dictionary without a search engine or ummm the search feature!?
During the implementation of the base dictionary, I had created these static Search forms (one on the homepage and the other on the Navbar used on the word layout) in preparation for this particular feature.
I just needed to pick-up from right there and get it working, easy work — if only that was true.
Something from the past
It is important to re-iterate that my initial plan was to build jargons.dev with Nextra as I admitted in the initial commit that:
...Nextra (this was infact my knight in shiny armor, I was looking to build with Nextra).
I am a React ⚛️ fan boy, big on Next.js; Nextra is a content-focus web framework that is built on Next.js. So I guess you can just understand why Nextra sounded like a that knight. During my initial exploration of Nextra, one feature stood out to me; the full-text search — I drooled ?over this one (I must confess).
The feature was powered by flexsearch — a zero-deps full-text search library; ooh boy I'm a big fan of lightweight and no/low dependencies. I dug into how Nextra uses this to index content at build-time for search; it was interesting.
So!?
I found myself hacking with flexsearch during my early encounter with Astro; as I followed the astro doc's build a blog tutorial, I went a notch further to implement a search feature very easily.
So, the experience from this implementation; I passed down to the search engine for jargons.dev.
The Search Engine
The task was pretty simple, I needed to..
- Get access or call it reference to all files inside of the dictionary directory of words - at this point it was the src/pages/word directory
- Get these files content indexed with flexsearch
- Plug in the search form and boom ?
Looks very easy! Maybe for the search indexing and actual searching, it was; but there was some lot of stuffs that went into getting there.
Integrating the first "Island" in jargons.dev
Astro by default takes a server-first approach, meaning it builds your site's HTML/CSS on server removing all client-side javascript (JS) automatically (unless you state other wise). Removing all JS assures performance improvement, but No JS means no interactivity; But if you want interactivity, Astro Island is one of the ways to go. I need the interactivity for the Search Engine so Island it is!
What's an "Island" though!?
I will put simply that an Island is an isolated interactive piece of component on a web page, whose HTML/CSS are rendered on the server-side and/but it's client-side javaScript are (hydrated) also bundled with it - NOT removed.
I gave a talk about Island at TILConf'24, Check it out to learn more.
Astro's offering
Astro offered support for integrating Islands out the box with my favorite UI library (yea, you guessed it, React) of many others. This allowed me build my static Search forms into a functional stuff.
Stuffs I did
- I started by adding the integration module (@astrojs/react) for the Island I needed to integrate; done pretty easily with the npx astro add react command
- I transferred all the static search forms into single React component (these are two differently sized forms); configured the component to render these at required size based on given props.
- I also implemented some sub-component within that are only consumed locally in the-same search component, these are...
- The SearchDialog - main component where the search operation is carried out
- The SearchResult component, etc...
- I implemented some custom keyboard shortcuts and keybinds that enables interactions with the search component (I'd like to call this "Search Island" from now on), these are...
- CTRL+K or ⌘K to start search
- ESC to close search
- ...and base required navigation buttons to navigate within search results
- I also added a few custom hooks to allow smooth sailing in the working of the search island, these are...
- useLockBody - a hook that disables scrolling once the search dialog is opened
- useRouter - a hook that I made as wrapper around some window.location methods, making them to feel like the known router libs in React, this is a hook I particularly consumed on the ENTER button click handler in the navigation button keybind on search results component in the search island.
- and useIsMacOS - which checks whether a machine is MacOS in order to determine the appropriate description text to render on the search form trigger; i.e. CTRL+K or ⌘K
- I added the imperative module - flexsearch;
- I retrieved access to files the directory of words using the Astro.glob() function super easily (too bad I couldn't talk about how powerful this function is; how glad I am it existed out-the-box in Astro and how much ease it brought into the flow of getting this search engine up and running) and plugged the returned array of word objects into a $dictionary state (maybe I should call this a store) powered by nanostore (another beautiful stuff right there)
- This $dictionary are then indexed with flexsearch, prepping them for later search.
Another Imperative feature: The Recent Searches
This is another imperative feature that I must talk about; This feature keeps track of searched items and stores them in localstorage to persist them on page reload; these store searched items are then render in a list on the homepage of the dictionary.
It also took integration as an Island, couple with a holding the value in a nanostore powered $recentSearches state.
My implementation of this feature isn't exactly perfect, and here are a list of some Issues that needed fix (at time of writing) to take it a step further down that route (even though we can never reach perfection, YEA for sure)
- Add Loading Component to Recent Searches Island - https://github.com/devjargons/jargons.dev/issues/31
- Bug: Search Operation Performed with Search Form in Navbar Overwrites LocalStorage - https://github.com/devjargons/jargons.dev/issues/10
- Enhancement: Word Editor - Second Iteration Features - https://github.com/devjargons/jargons.dev/issues/9
The PR
This is some long read now, I wish to keep this reads short... Here's the PR
feat: implement dictionary search engine
#5

This Pull Request implement the search functionality to the dictionary project. It uses @astro/react integration to power the Islands coupled with nanostore for state-management and flexsearch as text search library.
Changes Made
- Added the following astrojs integration and lib required to text search
- @astrojs/react
- @nanostores/react
- flexsearch
- Implemented the Search Island (a react component) within where other sub components are implemented for internal usage
- Implemented the SearchTrigger component which render a search field of two different sizes and used in two different places on the web page...
- size md - used on the main page of the web app
- size sm - used on the dictionary word layout navigation section
- Implemented the SearchDialog component, which renders only when the SearchTrigger is clicked
- Implemented the SearchInfo component, renders as default placeholder when no search term has been inputted in form field
- Implemented the SearchResult component, renders either search results or a message for a search results not found
- Implemented keybinds within Search island to allow the following operation with the stated keyboard shortcuts
- CTRL+K or ⌘K to open the search dialog without clicking on the search tigger
- ArrowUp, ArrowDown and Enter to allow navigation on the Search results list
- ESC to allow closure of search dialog
- Added the custom hooks for consumption on the Search island
- useIsMacOS - check whether current user is browsing the web app with a MacOS machine; this is used to determine the appropriate short to render on the search trigger; i.e. CTRL+K or ⌘K
- useLockBody - used to disable current viewport from scrolling when search dialog is opened
- useRouter - (instead of adding react-router to deps) this hook wraps around window.location and uses the assign object as push; mainly used in the SearchResult component to route to selected/clicked result page
- Implemented searchIndexing on Search island with flexsearch's Document method as preferred option
- Added a new search store for managing the search-related states with nanostores and @nanostores/react integration
- Added the following store values and actions
- $isSearchOpen - global state for managing the state of SearchDialog
- $recentSearches - state for keeping track of recently searched words; it works in collab with the localStorage to persist its value even after tab reloads
- $addToRecentSearchesFn - a store action that adds new item to $recentSearches store value
- Implemented the SearchTrigger component which render a search field of two different sizes and used in two different places on the web page...
- Added a $dictionary store for managing the entire dictionary entries; keeping it accesible to the client and used as value for searchIndex in the Search island
- Computed value for the dictionary store as early as possible from the layout/base with the Astro.glob() method indexing the entire dictionary directory
- Added the RecentSearches island which reads the value from the $recentSearches store and renders it on the homepage
Screencast
Full Demo
screencast-bpconcjcammlapcogcnnelfmaeghhagj-2024.03.25-13_32_30.webm
?
The above is the detailed content of Building jargons.dev [# The Dictionary Search Engine. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics











Python is more suitable for beginners, with a smooth learning curve and concise syntax; JavaScript is suitable for front-end development, with a steep learning curve and flexible syntax. 1. Python syntax is intuitive and suitable for data science and back-end development. 2. JavaScript is flexible and widely used in front-end and server-side programming.

The main uses of JavaScript in web development include client interaction, form verification and asynchronous communication. 1) Dynamic content update and user interaction through DOM operations; 2) Client verification is carried out before the user submits data to improve the user experience; 3) Refreshless communication with the server is achieved through AJAX technology.

JavaScript's application in the real world includes front-end and back-end development. 1) Display front-end applications by building a TODO list application, involving DOM operations and event processing. 2) Build RESTfulAPI through Node.js and Express to demonstrate back-end applications.

Understanding how JavaScript engine works internally is important to developers because it helps write more efficient code and understand performance bottlenecks and optimization strategies. 1) The engine's workflow includes three stages: parsing, compiling and execution; 2) During the execution process, the engine will perform dynamic optimization, such as inline cache and hidden classes; 3) Best practices include avoiding global variables, optimizing loops, using const and lets, and avoiding excessive use of closures.

Python and JavaScript have their own advantages and disadvantages in terms of community, libraries and resources. 1) The Python community is friendly and suitable for beginners, but the front-end development resources are not as rich as JavaScript. 2) Python is powerful in data science and machine learning libraries, while JavaScript is better in front-end development libraries and frameworks. 3) Both have rich learning resources, but Python is suitable for starting with official documents, while JavaScript is better with MDNWebDocs. The choice should be based on project needs and personal interests.

Both Python and JavaScript's choices in development environments are important. 1) Python's development environment includes PyCharm, JupyterNotebook and Anaconda, which are suitable for data science and rapid prototyping. 2) The development environment of JavaScript includes Node.js, VSCode and Webpack, which are suitable for front-end and back-end development. Choosing the right tools according to project needs can improve development efficiency and project success rate.

C and C play a vital role in the JavaScript engine, mainly used to implement interpreters and JIT compilers. 1) C is used to parse JavaScript source code and generate an abstract syntax tree. 2) C is responsible for generating and executing bytecode. 3) C implements the JIT compiler, optimizes and compiles hot-spot code at runtime, and significantly improves the execution efficiency of JavaScript.

Python is more suitable for data science and automation, while JavaScript is more suitable for front-end and full-stack development. 1. Python performs well in data science and machine learning, using libraries such as NumPy and Pandas for data processing and modeling. 2. Python is concise and efficient in automation and scripting. 3. JavaScript is indispensable in front-end development and is used to build dynamic web pages and single-page applications. 4. JavaScript plays a role in back-end development through Node.js and supports full-stack development.
