Is it possible to integrate a comprehensive full text search capability on a static website directly on the client side, without reliance on a database

There is a script that I came across, possibly in npm's source code, but I didn't write it myself. I'm intrigued by the idea of refactoring this code to potentially enable a quick web crawl of a static site and generate a list of URLs leading to pages with the highest search term hits. I'm not looking for anything complex like fuzzy search, just wondering if there's potential to implement a basic full-text search after reviewing this code. I would appreciate another set of eyes to provide input on this.


const fs = require("fs");
const path = require("path");
const npm = require("./npm.js");
const color = require("ansicolors");
const output = require("./utils/output.js");
const usageUtil = require("./utils/usage.js");
const { promisify } = require("util");
const glob = promisify(require("glob"));
const readFile = promisify(fs.readFile);
const didYouMean = require("./utils/did-you-mean.js");
const { cmdList } = require("./utils/cmd-list.js");

const usage = usageUtil("help-search", "npm help-search <text>");
const completion = require("./utils/completion/none.js");

const npmUsage = require("./utils/npm-usage.js");

const cmd = (args, cb) =>
  helpSearch(args)
    .then(() => cb())
    .catch(cb);

const helpSearch = async (args) => {
  if (!args.length) throw usage;

  const docPath = path.resolve(__dirname, "..", "docs/content");

  const files = await glob(`${docPath}/*/*.md`);
  const data = await readFiles(files);
  const results = await searchFiles(args, data, files);
  // if only one result, then just show that help section.
  if (results.length === 1) {
    return npm.commands.help([path.basename(results[0].file, ".md")], (er) => {
      if (er) throw er;
    });
  }

  const formatted = formatResults(args, results);
  if (!formatted.trim()) npmUsage(false);
  else {
    output(formatted);
    output(didYouMean(args[0], cmdList));
  }
};

const readFiles = async (files) => {
  const res = {};
  await Promise.all(
    files.map(async (file) => {
      res[file] = (await readFile(file, "utf8"))
        .replace(/^---\n(.*\n)*?---\n/, "")
        .trim();
    })
  );
  return res;
};

// More code...
module.exports = Object.assign(cmd, { usage, completion });

Answer №1

When it comes to implementing a client-side text search on your website, the key factor to consider is how your site is structured and generated. It is possible to make it work without any issues. However, it is important to avoid crawling the site on the client-side. Instead, consider generating a data file during the build process and then using that as the basis for your search functionality.

If your website is built using a static site generator, you can leverage this tool to create a JSON file containing all the necessary content. Alternatively, if your site consists of static assets only, you can develop a custom script to extract the content and generate the required data file.

There are numerous libraries available that facilitate searching through a JSON object, such as fuse.js.

One potential challenge with implementing a client-side search feature is the volume of text that needs to be searched. If your site contains a significant amount of content, loading everything into memory on the client-side could lead to performance issues. It is recommended to conduct thorough testing to ensure optimal functionality based on your specific requirements.

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

Why does the <select> dropdown flash when I select it?

Currently utilizing Angular 1.3 and Bootstrap 3.3.x CSS without the JS functionality. There is also an interesting animated GIF embedded within. <div class="form-group"> <div class="col-lg-3"> <label clas ...

Other elements are unable to conceal Material UI InputBase

Displayed below is a navigation bar that sticks to the top, followed by rows of InputBase components from material-ui. Despite setting the background color of the nav bar to white, the input always appears above the nav. This strange behavior stopped when ...

JavaScript: Creating Custom IDs for Element Generation

I've been developing a jeopardy-style web application and I have a feature where users can create multiple teams with custom names. HTML <!--Score Boards--> <div id="teamBoards"> <div id="teams"> ...

The second request made with $.ajax is bypassed

I have been working on integrating the Google Maps JavaScript API and attempting to update a heat map when a user clicks on a specific div element. The latitude and longitude data used for the heatmap are fetched from local JSON files. While I have success ...

Having trouble getting npm installation and npm dev to work with Laravel?

Hello everyone, [I am seeking assistance and providing detailed information to ensure all necessary details are included. I encountered an issue after installing Laravel where the webpage displayed errors stating that app.css and app.js were not found. A ...

Display a div based on search results

I recently encountered an issue with a script that needs modification to display different divs based on search criteria. Originally, I used this script for a contact list but now need it to perform another function. View the original code (JSFiddle) Here ...

How can the token be verified when authorizing Google OAuth 2.0 on the server side?

Unable to validate the user token ID on the server side despite following Google's guide at https://developers.google.com/identity/sign-in/web/backend-auth In JavaScript, I retrieve the id token and send it to the server: var googleUser = auth2.cur ...

What is the proper way to credit the glyphicons element in Twitter's bootstrap framework?

According to the section on icons in the Base CSS page of GitHub's Twitter bootstrap, Glyphicons Halflings were not originally available for free. However, thanks to an agreement between Bootstrap and the creators of Glyphicons, developers can now use ...

Issue with Vue-Validator form validation not functioning properly on JS Fiddle

I'm having trouble with vue-validator on JSFiddle. Can someone please assist in troubleshooting the issue so I can proceed with my main question? Check out JSFiddle Html: <div id="app"> <validator name="instanceForm"> & ...

Navigating through directories (including nested ones) containing images in React Native; what's the best way to approach this

I am currently attempting to organize groups of images. Within the directory ./assets, there are several folders structured as follows: ./assets ├── 1x3 │ ├── 1.jpg │ ├── 2.jpg │ └── 3.jpg └── 3x3 ├── 1. ...

I can't figure out why I'm receiving undefined even though all the variables are populated with the necessary

I have been working on a project that involves implementing email and password authentication using Firebase. However, I encountered an error when the user submits their credentials: FirebaseError: Firebase: Error (auth/admin-restricted-operation). at ...

The Next.js template generated using "npx create-react-app ..." is unable to start on Netlify

My project consists solely of the "npx create-react-app ..." output. To recreate it, simply run "npx create-react-app [project name]" in your terminal, replacing [project name] with your desired project name. Attempting to deploy it on Netlify Sites like ...

Does LABJS include a feature for executing a callback function in the event of a timeout during loading?

When using LabJS to asynchronously load scripts with a chain of dependencies, if one of the scripts breaks (due to download failure or connection timeout), it seems that the remaining scripts in the chain will not be executed. Is there a way to define a ...

Deploying an Angular application created using Yeoman to Heroku

I have been following some instructions on how to deploy my project, such as this guide or this tutorial. However, I am unable to get it to work properly. This is the code in my server.js file: var app, express, gzippo, morgan; gzippo = require('gz ...

Divide a collection of objects into groups based on 2-hour time spans

I have an array of objects that I need to split into chunks of 2 hours each, starting on the hour (e.g. 10.00 - 12.00, 12.00 - 14.00, etc). Here is my current solution, but I feel like it may not be the most efficient: Please consider the day variable, w ...

Using various jQuery autocomplete features on a single webpage

UPDATE I have observed that the dropdown elements following the initial one are not being populated correctly. .data( 'ui-autocomplete' )._renderItem = function( ul, item ) { return $( "<li></li>" ) .data( "i ...

Is there a way to refresh the current page in Ionic 3 when the browser is reloaded?

I have encountered a problem in my work with an Ionic 3 App. I am looking for a solution where the browser will refresh the current page instead of redirecting me to the home page. Is this achievable? I attempted to solve it using the following code: thi ...

What is causing the numerous vulnerabilities to appear when I run my 'npm install' command?

Whenever I run npm install on a GitHub project I've cloned or when installing packages for my personal projects, I always encounter at least 20 vulnerabilities. It's strange because the creators of YouTube tutorials never seem to have any vulnera ...

Encountering an "ENOTFOUND error" in Npm during the package installation process

When trying to install an npm package, I encountered the following error: npm ERR! code ENOTFOUND npm ERR! errno ENOTFOUND npm ERR! network request to https://registry.your-registry.npme.io/npmrc failed, reason: getaddrinfo ENOTFOUND registry.your-registry ...

How can you gather user data on a website without relying on a database and making it voluntary?

In order to streamline the process, the user should be able to send a preformatted email with the click of a button or have their data stored securely without leaving the site. The goal is to avoid the extra step of using a mailto: link, unless the email c ...