What steps should I follow to create a Lunr search functionality for Markdown MD files?

Currently, I am in search of a suitable lunr search implementation for my MD (Markdown) documents spread throughout my React/NextJS website. Our website contains a plethora of Markdown docs within both blog and regular "docs" sections, necessitating a robust search functionality for users to easily navigate through topics. Although our MDs are dynamically rendered via NextJS, we require a server-side search capability to enhance security measures by restricting user access solely to result retrieval, rather than enabling direct client/browser side page searches.

  • To accommodate this requirement, our plan involves building the lunr search index during site construction (which should be relatively straightforward given the static nature of our content).
  • We intend to utilize API endpoint routing for executing server-side searches on the created search index.
  • For user interaction, we will leverage nextJS clientside capabilities to interface with the API endpoint for initiating searches and returning results.

While I possess a decent understanding of lunr operations, including index construction, API router setup, and final result rendering, my primary challenge lies in integrating the index creation process with the actual searchable text derived from MD documents. This raises concerns about omitting non-searchable meta information present in MD files or any irrelevant HTML tags within the corresponding rendered HTML versions. Consequently, I'm on the lookout for an existing NPM package that addresses these specific complexities.

Furthermore, I'm interested in exploring methods to refine the search index structure to generate visually appealing search results featuring brief previews displaying relevant sentences alongside each match, instead of just listing page titles.

Answer №1

If you want to achieve this, the solution is simple - just perform a double search.

  1. Firstly, retrieve the page from the backend and make it accessible through an API.
  2. Next, within the user interface, execute another search to highlight the necessary words.

Check out this fiddle for a demonstration.

To streamline the process, I utilized the "react-highlight-words" library.

Code:

Imports

<script src="https://unpkg.com/react@17/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="1a687f7b796e3772737d7276737d726e376d75687e695a2a342b2b28342e20">[email protected]</a>/dist/main.min.js"></script>

Actual Logic

import React, { useState, useEffect, Component } from 'react';
import { render } from 'react-dom';
import Highlighter from 'react-highlight-words';

const App = () => {
  const [text, setText] = useState('');
  const [data, setData] = useState('');
  const HINT = 'Search any name';

  const searchName = async text => {
    const URI = `https://api.nationalize.io/?name=${text}`;
    return fetch(URI);
  };

  useEffect(() => {
    (async () => {
      if (!text) {
        setData(HINT);
        return;
      }

      const res = await searchName(text);
      const data = await res.text();
      setData(data);
    })();
  }, [text]);

  return (
    <div>
      <input value={text} onChange={e => setText(e.target.value)} />
      <br />
      <br />

      <Highlighter searchWords={[text]} textToHighlight={data} />
    </div>
  );
};

render(<App />, document.getElementById('root'));

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

I am having trouble retrieving any data when using jQuery to post JSON data

I am struggling with some HTML and JavaScript code. Here is what I have: <html> <head> </head> <body> <script src="view/backoffice/assets/plugins/jquery/jquery-1.11.1.min.js" type="text/javascript"></sc ...

Retrieving Blocked Images with Selenium: A Step-by-Step Guide

HTML: <html> <head> <body onload="document.getElementById('a').style.display='block';"> <div id="a" align="center" onclick="document.location.reload();" style="display: block; cursor: pointer;"> <img width="9 ...

Best practices for using parent and child methods in Vue applications

I'm exploring the most effective approach to creating a modal component that incorporates hide and show methods accessible from both the parent and the component itself. One option is to store the status on the child. Utilize ref on the child compo ...

Deleting an object with javascript in django: A step-by-step guide

Is there a way to use JavaScript to create a confirmation window before deleting an item? <div class="card-footer"> <a href="{% url 'course_delete' student.slug %}"><button>Delete</button>&l ...

Angular directive ceases to trigger

I am currently working on implementing an infinite scrolling directive. Initially, when the page loads and I start scrolling, I can see the console log. However, after the first scroll, it stops working. It seems like it only triggers once. Can anyone poi ...

Differentiate input elements with custom styling

I'm experiencing an issue while trying to style a specific form field in Angular 7. The style doesn't seem to be applying properly. Below is my form structure: <ul> <li> <mat-form-field *ngIf="number"> <input ma ...

"The Django querydict receives extra empty brackets '[]' when using jQuery ajax post to append items to a list in the app

Currently, I am tackling a project in Django where I am utilizing Jquery's ajax method to send a post request. The csrftoken is obtained from the browser's cookie using JavaScript. $.ajax({ type : 'POST', beforeSend: funct ...

Utilizing Next.JS and Nodemailer to seamlessly send emails through a contact form

I'm facing an issue with my contact form in next.js. Everything was working fine until I deployed it on Vercel. Although I don't see any errors, I am not receiving emails on my Gmail account after submitting the form. Additionally, I am not getti ...

Error: The property 'updateOne' cannot be read because it is undefined

I have been struggling to update an array in my MongoDB database, despite following the steps outlined in the official documentation. I can't seem to make it work. Can anyone provide assistance? I went through the official documentation, but unfortun ...

JavaScript is claiming that my class method is invalid, despite the fact that it is obviously a valid function

Implementing a genetic algorithm using node has been my latest challenge. After browsing through the existing questions on this topic, I couldn't find anything relevant to my issue. The problem arises when I attempt to call the determine_fitness metho ...

Uploading Files Using Ajax to a PHP Class

Having some trouble with my file upload using AJAX to post to an object-oriented PHP class. Here's the AJAX code: var handleUpload = function(event) { event.preventDefault(); event.stopPropagation(); var fileInput = document.getElement ...

ESLint detected a promise being returned in a function argument where a void return type was expected

I'm encountering a recurring error whenever I run my ESLint script on multiple routers in my server. The specific error message is as follows: error Promise returned in function argument where a void return was expected @typescript-eslint/no-misuse ...

Can WebGL be configured to render offscreen without its canvas being directly connected to the DOM?

Searching for an answer to what I believed would be a simple question has proven to be quite challenging. My goal is to utilize WebGL for image processing and generation tasks, with the intention of working offscreen. Specifically, I aim for WebGL to rende ...

When attempting to perform conditional rendering in React using a stateless functional component, I encounter an error stating "Unexpected token, expected ,"

Here is the code snippet: 'use strict' import React from 'react' import { connect } from 'react-redux' import { Panel, Col, Row, Well, Button } from 'react-bootstrap' const Cart = ({ cart }) => { const cartI ...

I'm having trouble getting my innerHTML command to update anything on the webpage, and the reason is eluding me

Below is the code snippet provided: <div id="js"><button onclick="document.getElementById('js').innerHTML=('<form> <input type=text name=tick1></input> <input type=text name=tick2></input> ...

Enhance your user interface by incorporating badges into specific elements using Bootstrap version 5.2

I am currently using the most recent version of Bootstrap v5.2 and Vue 3 (for learning purposes). While searching on Stackoverflow, I came across a similar question, but it was related to an older Bootstrap version. In my project, I have a select element ...

Utilize the return value within a .map function following the completion of a request.get call

Essentially, for security reasons, I need to convert an image from a URL to base64. Currently, I have two functions in place. One function is responsible for converting the image from the URL to base64, and the other function is iterating over the databas ...

Steps to obtain an Element binding from a Svelte component

Is it possible to retrieve the bounding client rect of an anchor element? I typically mark this using the syntax bind:this={someVariable}. However, when I add this code to a Svelte component, I receive a different object that Svelte uses to represent a c ...

Explore the possibilities with Intel XDK's customizable keyboard feature

I recently started using Intel XDK for development and I encountered the following issue: I have an input text field (HTML) and I need to restrict user input to only numbers, decimals, and negative sign when they click on the field. How can I achieve this ...

Decoding user input parameters within a vue module

It seems like I am hitting a wall when it comes to finding solutions for this particular issue. Currently, I have a component that is supposed to retrieve data from a file and display it. My intention is to only pass the filename to the component so that ...