Skip to content

How to Add Search to a Static WordPress Site for Free Using Lunr

If you have a static WordPress site or you’re strongly considering launching one, then you’re probably already aware of its default limitations. One of the big ones is the inability to add a search function to your site. This is due to the fact that the “regular way” search works on a standard WordPress site is via PHP and static sites don’t use PHP. The roadblock is obvious here.

But with a little bit of creative thinking, you can use a free, open-source JavaScript library called Lunr (along with a few other tools) to get around it and add search to your static site anyway.

How to Add Search to a Static WordPress Site

So if you’re ready to channel some inner JCVD Bloodsport energy into your WordPress static site then let’s get started.

What is Lunr.js and why it’s a perfect search solution for static sites 🌙

⏭️ If you’re already sold and just want the implementation steps, click here to skip straight to the tutorial.

Lunr.js is a compact JavaScript library that’s designed specifically for browser-based search. Unlike traditional WordPress search which hammers your database with queries, Lunr.js handles everything on the client side. No PHP processing. No API calls to external services. Just pure, speedy JavaScript goodness.

The best part is that adding Lunr.js to your static site won’t increase your hosting costs one cent. Your site will still run on Cloudflare Pages (or a similar service) with all the benefits I covered in the main guide on how to launch a static site.

With that said, I want to briefly set some proper expectations. Lunr.js has a lot going for it, but it’s not a flawless solution. Here’s what to expect…

The ups and downs of using Lunr.js ⬆️⬇️

There are two main things to take into consideration when deciding if this is going to be a good search solution for your static site:

  • Size of your site.
  • Search quality trade-offs.

Performance considerations for larger sites

Lunr.js works brilliantly for small to medium-sized sites, but there are some practical limits to consider:

  • Index size and loading time: For every 100 posts, expect roughly 100-200KB of index file size. This might not sound like much, but a site with 1,000+ posts could end up with a 1MB+ index that would need to load in visitors’ browsers before searching begins. For smaller sites, this loading is nearly instantaneous, but larger sites might experience a noticeable delay.
  • Memory usage: The entire index loads into the browser’s memory. For very large sites, this could potentially slow down the visitor’s browser (i.e., not just the tab with your search page but all their tabs).

The bottom line is that if your site has fewer than 500 pages, you’ll likely be fine.

Search quality: What you gain and what you give up

Compared to server-side search solutions, Lunr.js makes some tradeoffs:

The good stuff:

  • Relevance-based ranking out of the box.
  • Fuzzy matching to deal with accidental typos.
  • Term stemming (finding “running” when searching for “run”).

The compromises:

  • No natural language processing for understanding query intent.
  • Limited ability to handle complex queries with many search operators. This isn’t an enormous drawback since most people don’t use search operators anyway, but it’s just something to be aware of in case it’s important to you. The solution I’m going to give you includes two (wildcard and exact match) search operators which will suffice for the vast majority of use cases.

For most personal blogs, portfolio sites, and small business websites, these tradeoffs are completely reasonable. Your visitors will still get helpful, relevant results.

Phase one: Set up your development environment 👨🏻‍💻

Now that you understand what Lunr.js is all about, it’s time to roll up your sleeves and get everything ready for implementation.

Required tools 🧰

To pull this off, you’ll need a few essentials:

  1. Your local WordPress site (with the Simply Static plugin).
  2. Lunr.js library.
  3. A code editor (e.g., Sublime Text or even the simple text editors that come installed on both Mac and Windows).
  4. Terminal on Mac / Command Line on Windows.

If you followed my previous guide on setting up a static WordPress site, then all of these – with the exception Lunr.js perhaps – will be familiar to you.

⚠️ Note: My demo static site was built using Neve FSE, which is a block theme, but you can use this tutorial for classic themes as well. There’s only one tiny difference in the way it gets implemented and that difference happens right at the beginning of the tutorial – I’ll point it out.

Add Lunr.js to your local WordPress environment 🖥️

Assuming you are using Local by Flywheel, the first step is to get into your WordPress site. Make sure the One-click admin is toggled on and then tap on the WP Admin button:

Accessing local WordPress site via Local by Flywheel.

Next, from your WordPress dashboard, go to AppearanceEditor.

Accessing the full site editor through wp-admin.
⚠️ If you don't see 'Editor' it means you are using a classic theme (click for instructions)

As I mentioned above, this is the only part of the guide where there’s a mini fork in terms of approach. For classic theme users, if you don’t already have it installed, you need to install and activate the Header and Footer scripts plugin. Then from the WordPress dashboard, go to Settings → Header and Footer Scripts and in the Scripts in header section, add the following code:

<script src="https://unpkg.com/lunr/lunr.js"></script>Code language: HTML, XML (xml)

After you add the code and save, click here to skip ahead and resume the tutorial at the appropriate next step.

This will bring you into the Full Site Editor. Select Patterns from the side menu:

Accessing Patterns in FSE.

If you’re not specifically using the Neve FSE theme but another block theme then the next screen is going to look slightly different.

Nonetheless, you should be able to see an option for Header under All template parts.

This is because every theme is going to have at least one header template where your navigation menu and other common features are stored (e.g., site icon, site title). Many themes actually have multiple header templates (that includes Neve FSE), but the default one is typically called “Header” with no other words.

You might also see “Main Header” or “Header Main.” The idea is to look for the one that sounds the most like it’s the default option. Once you have it, tap the three vertical dots and click on Edit:

Accessing the Header template in FSE.

Next, you will need to add a Custom HTML block to the header template, which means you’ll first need to get to the highest-level parent block by clicking anywhere inside the header. After that:

  1. Click the farthest left button repeatedly until you reach the top parent block.
  2. Once there, click the little + icon on the bottom right to add a new block.
  3. Type in html.
  4. Click on Custom HTML to add the block.
Editing the Header template in FSE.

Copy the code snippet below and paste it into the HTML block:

<script src="https://unpkg.com/lunr/lunr.js"></script>Code language: HTML, XML (xml)
Adding lunr.js snippet into the Header template.

Click Save to apply the changes.

Create a search test page 🔎

After successfully adding Lunr.js to your header template, the next step is to create a dedicated search page where your site visitors will go so they can search your site:

From your WordPress dashboard, go to Pages → Add New Page.

Once you’re inside the block editor, you can get to work.

First, give the page a name. There’s no need to be creative here. “Search” or “Search + Your Website’s Name” will probably work for 99% of websites.

Next, add a Group block to contain everything:

Click the + icon, type group into the search field and select the Group block. Then click on the first option, which just looks like a single rectangle:

Adding a parent Group block in the block editor on the Search page.

Inside the Group block, add the following:

  • A Heading block with text like “Search Our Site.”
  • A Paragraph block with brief instructions (e.g., “Type what you’re looking for. Be descriptive, but concise”).

Make sure that as you are adding the two blocks that you tap the far left button so when you click the + icon, it’ll be inside the Group parent block:

Adding title and description of the search page.

Now for the crucial part – you need to add an HTML block for the search interface. Make sure you are inside the Group parent block and then:

  • Click the + icon to add a new block.
  • Search for html and select the Custom HTML block.
  • Paste the following code into it:
<div class="lunr-search-container">
  <div class="lunr-search-form">
    <input type="text" id="lunr-search-input" placeholder="Search for..." class="lunr-search-input">
    <button id="lunr-search-button" class="lunr-search-button">Search</button>
  </div>
  <div id="lunr-search-results" class="lunr-search-results"></div>
</div>Code language: JavaScript (javascript)

Below this, add three more HTML blocks.

The code for the first one will add a note on how to use two search operators – the wildcard and exact match – for different needs:

<div class="search-tips">
  <small>
    <strong>Search tips:</strong> 
    Use * for partial matches (i.e., design* finds design, designer) and " " for exact phrases (i.e., "static site").
  </small>
</div>Code language: HTML, XML (xml)

You could technically also add the above as just a regular paragraph block, but using the <div class="search-tips"> allows for some minor styling that gets pulled from the next block below. If you do choose to use a paragraph block instead, you should still add the CSS code 👇🏻 because it sets the look for your entire search block. The search tips are only a small part of that.

Click to reveal CSS code for styling 👨🏻‍💻
<style>
  .lunr-search-container {
    max-width: 600px;
    margin: 40px auto;
    padding: 20px;
    background-color: #f9f9f9;
    border-radius: 8px;
    box-shadow: 0 2px 5px rgba(0,0,0,0.05);
  }
  
  .lunr-search-form {
    display: flex;
    gap: 10px; /* This creates space between input and button */
  }
  
  .lunr-search-input {
    flex: 1;
    padding: 12px 15px;
    font-size: 16px;
    border: 2px solid #ddd;
    border-radius: 4px;
    outline: none;
    transition: border-color 0.2s;
  }
  
  .lunr-search-input:focus {
    border-color: #0073aa;
  }
  
  .lunr-search-button {
    padding: 12px 24px;
    font-size: 16px;
    background-color: #0073aa;
    color: white;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    transition: background-color 0.2s;
    white-space: nowrap;
  }
  
  .lunr-search-button:hover {
    background-color: #005177;
  }
  
  /* Search tips styling */
  .search-tips {
    margin-top: 20px;
    margin-bottom: 15px;
    opacity: 0.8;
    font-size: 1.0em;
  }
  
  .lunr-search-results {
    margin-top: 30px;
    min-height: 50px;
  }
  
  .lunr-result-item {
    margin-bottom: 20px;
    padding-bottom: 20px;
    border-bottom: 1px solid #eee;
  }
  
  .lunr-result-title {
    font-size: 18px;
    font-weight: bold;
    margin-bottom: 8px;
  }
  
  .lunr-result-title a {
    color: #0073aa;
    text-decoration: none;
  }
  
  .lunr-result-snippet {
    font-size: 14px;
    line-height: 1.6;
    color: #555;
  }
  
  .lunr-no-results {
    font-style: italic;
    color: #777;
  }
  
  /* Highlight styling for search results */
  .lunr-highlight {
    background-color: #ffeb3b;
    padding: 0 2px;
    border-radius: 2px;
  }
</style>Code language: HTML, XML (xml)

The third one is actually just a placeholder. It will eventually contain your JavaScript code but you’re adding the placeholder for now so you can test it to make sure everything is working properly:

Click to reveal placeholder JavaScript code 👨🏻‍💻
<script>
  document.addEventListener('DOMContentLoaded', function() {
    // This is where our Lunr.js search implementation will go
    console.log('Search page loaded and ready for Lunr implementation');
    
    // Elements
    const searchInput = document.getElementById('lunr-search-input');
    const searchButton = document.getElementById('lunr-search-button');
    const resultsContainer = document.getElementById('lunr-search-results');
    
    // Just to confirm everything is connected properly
    searchButton.addEventListener('click', function() {
      resultsContainer.innerHTML = '<p>Search functionality coming soon! You searched for: <strong>' + 
        searchInput.value + '</strong></p>';
    });
  });
</script>Code language: HTML, XML (xml)

Testing is the next step, but before you do that, quickly do one more spot check to ensure that all of the blocks were added inside the Group block. You should see a thin line that surrounds everything with all six of your blocks (i.e., heading, paragraph, four HTML) inside of it:

Search interface on the backend with CSS and JS added.

Testing the search interface

Next, click on Save Draft on the top right and then the preview button to see what your search page looks like on the frontend of your site.

Try typing something in the search box and clicking the Search button. You should see a message that says Search functionality coming soon! followed by whatever you typed.

Testing search functionality on the frontend of the site.

If everything displays correctly, congratulations! You’ve successfully set up the search interface. The search won’t actually work yet because you haven’t created your search index, but the foundation is in place.

Go back to the block editor tab and click on Publish. You’re now ready for phase two.

Phase two: Create a search index generator 🏗️

For Lunr.js, your search index needs to be a structured JSON file that contains all the searchable content from your WordPress site. This file will get loaded by your JavaScript code when someone visits the search page. Although the JSON file could be created manually, it’s more efficient to automate it. For that, you’ll need a mini custom-made plugin.

Build a custom content extraction plugin 🔌

First, open up Local by Flywheel and make sure that the site you are working on is selected (if you have more than one site). Then do the following:

  • Tap on the Site folder located directly below your site name at the top. This will open up Finder on Mac (shown below) or File Manager on Windows and you’ll see some folders there.
  • Go into app, followed by public, followed by wp-content, and finally plugins.
  • Inside of plugins, create a new folder called lunr-index-generator:
Using the Site folder button in Local by Flywheel and then navigating through Finder to locate the lunr index generator folder.

Open up Sublime Text or whatever code/text editor you used earlier and paste the code below into it. Then save the file as lunr-index-generator.php inside of this new lunr-index-generator folder:

Click to reveal the plugin code 👨🏻‍💻
<?php
/**
 * Plugin Name: Lunr Index Generator
 * Description: Creates a search index for Lunr.js from your WordPress content
 * Version: 1.0
 * Author: Lunr
 */

// Don't allow direct access to the plugin file
if (!defined('ABSPATH')) {
    exit;
}

// Add admin menu item
function lunr_index_generator_menu() {
    add_management_page(
        'Generate Lunr Search Index',
        'Lunr Search Index',
        'manage_options',
        'lunr-index-generator',
        'lunr_index_generator_page'
    );
}
add_action('admin_menu', 'lunr_index_generator_menu');

// Create the admin page
function lunr_index_generator_page() {
    ?>
    <div class="wrap">
        <h1>Generate Lunr.js Search Index</h1>
        <p>Click the button below to generate a search index of your site's content for use with Lunr.js.</p>
        
        <form method="post" action="">
            <?php wp_nonce_field('lunr_generate_action', 'lunr_nonce'); ?>
            
            <p>
                <label>
                    <input type="checkbox" name="include_posts" value="1" checked> 
                    Include Posts
                </label>
            </p>
            
            <p>
                <label>
                    <input type="checkbox" name="include_pages" value="1" checked> 
                    Include Pages
                </label>
            </p>
            
            <p>
                <input type="submit" name="lunr_generate" class="button button-primary" value="Generate Index">
            </p>
        </form>
        
        <?php
        // Handle form submission
        if (isset($_POST['lunr_generate']) && check_admin_referer('lunr_generate_action', 'lunr_nonce')) {
            lunr_generate_index();
        }
        ?>
    </div>
    <?php
}

// Function to clean content for search
function clean_content_for_search($content) {
    // Remove common form field patterns
    $content = preg_replace('/Name:.*?Email:.*?Message:.*?/i', '', $content);
    // Clean up extra whitespace
    $content = preg_replace('/\s{2,}/', ' ', $content);
    return trim($content);
}

// Generate the search index
function lunr_generate_index() {
    $include_posts = isset($_POST['include_posts']) ? true : false;
    $include_pages = isset($_POST['include_pages']) ? true : false;
    
    // Initialize the documents array
    $documents = array();
    
    // Get posts if selected
    if ($include_posts) {
        $posts = get_posts(array(
            'post_type' => 'post',
            'post_status' => 'publish',
            'numberposts' => -1,
        ));
        
        foreach ($posts as $post) {
            $documents[] = array(
                'id' => $post->ID,
                'url' => get_permalink($post->ID),
                'title' => $post->post_title,
                'content' => clean_content_for_search(wp_strip_all_tags($post->post_content)),
                'excerpt' => get_the_excerpt($post->ID),
                'date' => get_the_date('', $post->ID)
            );
        }
    }
    
    // Get pages if selected
    if ($include_pages) {
        $pages = get_posts(array(
            'post_type' => 'page',
            'post_status' => 'publish',
            'numberposts' => -1,
        ));
        
        foreach ($pages as $page) {
            // Skip the search page itself
            if ($page->post_name === 'search') {
                continue;
            }
            
            $documents[] = array(
                'id' => $page->ID,
                'url' => get_permalink($page->ID),
                'title' => $page->post_title,
                'content' => clean_content_for_search(wp_strip_all_tags($page->post_content)),
                'excerpt' => get_the_excerpt($page->ID),
                'date' => get_the_date('', $page->ID)
            );
        }
    }
    
    // Create the JSON file
    $json_data = json_encode($documents, JSON_PRETTY_PRINT);
    
    // Save file to the active theme directory
    $theme_dir = get_stylesheet_directory();
    $file_path = $theme_dir . '/lunr-search-index.json';
    $file_saved = file_put_contents($file_path, $json_data);
    
    if ($file_saved) {
        echo '<div class="notice notice-success"><p>Search index generated successfully! File saved to: <code>' . $file_path . '</code></p></div>';
    } else {
        echo '<div class="notice notice-error"><p>Error: Could not save the search index file. Please check file permissions.</p></div>';
    }
    
    // Also output as downloadable
    echo '<div class="notice notice-info"><p>You can also download the index file directly:</p>';
    echo '<p><a href="#" id="download-json" class="button">Download JSON</a></p>';
    echo '<script>
        document.getElementById("download-json").addEventListener("click", function(e) {
            e.preventDefault();
            const blob = new Blob([' . json_encode($json_data) . '], {type: "application/json"});
            const link = document.createElement("a");
            link.href = URL.createObjectURL(blob);
            link.download = "lunr-search-index.json";
            link.click();
        });
    </script></div>';
}Code language: HTML, XML (xml)

The next step is to activate it.

Activate the plugin and generate your JSON file

Go back to your WordPress site and activate the plugin like you would any other plugin: PluginsInstalled PluginsActivate.

Activating Lunr Index Generator plugin from wp-admin.

After activation, go to Tools → Lunr Search Index.

Check which content types you want to include (i.e., posts, pages) and click on Generate Index. The plugin will automatically save the JSON file for you.

⚠️ Copy the location to the right of where it says File saved to.

Also, even though the plugin saves it, download a copy anyway so you can quickly inspect it:

Generating JSON index file and copying location.

Once you open it up, you should see text that corresponds to your pages and/or posts. For example, mine looked like this:

Inspecting the JSON file.

If everything is good, you can go ahead and add it to your static setup.

✋ Assuming you read and followed my tutorial on setting up a WordPress static site, then you’ll already have the Simply Static plugin installed and configured. If that’s not the case, then I suggest heading to the tutorial first and then coming back here. Alternatively, if you’re using a different solution and would like to stick with it, then you’ll need to find the equivalent of what I’m about to show you below.

From your wp-admin, go to Simply StaticGeneral and paste the location of the JSON file you set aside into the Additional Files and Directories window. It should look something like this:

/Users/username/Local Sites/site-name/app/public/wp-content/themes/theme-name/lunr-search-index.jsonCode language: PHP (php)

The difference being that username, site-name, and theme-name should be your actual information.

Adding JSON file to Simply Static plugin.

Phase three: Implement the search interface 🔋

At this point you’ve got your Lunr.js library loaded and a fresh JSON index full of content. Now comes the fun part – bringing it all together to create a working search feature for your site visitors.

Connect the dots 🔗

Remember that placeholder JavaScript you added to your search page earlier? It’s time to swap it out for the real deal. Head back to your search page and edit it:

  1. Go to Pages → All Pages in your WordPress dashboard.
  2. Find your Search page and click Edit.
  3. Locate your Group block containing the HTML blocks.
  4. Find the JavaScript HTML block (the most bottom one on the page) and replace the placeholder code with the full implementation below – but ⚠️ for this line fetch('wp-content/themes/YOUR-THEME-NAME/lunr-search-index.json') substitute /YOUR-THEME-NAME/ with your actual theme name. For example, in my file, that line looked like this: fetch('/wp-content/themes/neve-fse/lunr-search-index.json'). The completed line should also partially match what you added to the Additional Files and Directories window in the Simply Static plugin. The only difference is that in the plugin you wrote the full path, whereas here it starts from /wp-content/.
Click to reveal code 👨🏻‍💻
<script>
document.addEventListener('DOMContentLoaded', function() {
  const searchInput = document.getElementById('lunr-search-input');
  const searchButton = document.getElementById('lunr-search-button');
  const resultsContainer = document.getElementById('lunr-search-results');
  
  let lunrIndex = null;
  let allDocuments = [];
  
  fetch('/wp-content/themes/YOUR-THEME-NAME/lunr-search-index.json')
    .then(response => {
      if (!response.ok) {
        throw new Error('Network response was not ok');
      }
      return response.json();
    })
    .then(documents => {
      allDocuments = documents;
      
      lunrIndex = lunr(function() {
        this.pipeline.remove(lunr.stemmer);
        this.searchPipeline.remove(lunr.stemmer);
        
        this.ref('id');
        this.field('title', { boost: 10 });
        this.field('content');
        this.field('excerpt', { boost: 5 });
        
        documents.forEach(function(doc) {
          this.add(doc);
        }, this);
      });
      
      console.log('Search index loaded and ready!');
      
      searchButton.disabled = false;
    })
    .catch(error => {
      console.error('Error loading search index:', error);
      resultsContainer.innerHTML = '<p class="lunr-error">Sorry, there was a problem loading the search index. Please try again later.</p>';
    });
  
  function performSearch() {
    const query = searchInput.value.trim();
    
    if (query === '' || lunrIndex === null) {
      return;
    }
    
    const enhancedQuery = query.split(' ')
      .map(term => {
        if (term.length > 3) {
          return `${term}~1^10 ${term}^15`;
        } else {
          return `${term}^15`;
        }
      })
      .join(' ');
    
    try {
      const results = lunrIndex.search(enhancedQuery);
      displayResults(results, query);
    } catch (error) {
      console.error('Search error:', error);
      resultsContainer.innerHTML = `<p class="lunr-error">Sorry, there was an error with your search. Try using simpler search terms.</p>`;
    }
  }
  
  function displayResults(results, query) {
    resultsContainer.innerHTML = '';
    
    if (results.length === 0) {
      resultsContainer.innerHTML = `<p class="lunr-no-results">No results found for <strong>${query}</strong>. Try different keywords.</p>`;
      return;
    }
    
    resultsContainer.innerHTML = `<p class="lunr-results-count">Found ${results.length} result${results.length !== 1 ? 's' : ''} for <strong>${query}</strong>:</p>`;
    
    const resultsList = document.createElement('div');
    resultsList.className = 'lunr-results-list';
    
    results.forEach(result => {
      const doc = allDocuments.find(doc => doc.id.toString() === result.ref);
      if (!doc) return;
      
      const resultItem = document.createElement('div');
      resultItem.className = 'lunr-result-item';
      
      const title = document.createElement('div');
      title.className = 'lunr-result-title';
      const titleLink = document.createElement('a');
      titleLink.href = doc.url;
      titleLink.textContent = doc.title;
      title.appendChild(titleLink);
      
      const snippet = document.createElement('div');
      snippet.className = 'lunr-result-snippet';
      
      const snippetText = doc.excerpt || doc.content;
      
      const cleanedSnippet = snippetText
        .replace(/Name:.*?Email:.*?Message:.*?/gi, '')
        .replace(/\b(Submit|Send|Post|Button|Click here)\b/g, '')
        .replace(/\s{2,}/g, ' ')
        .trim();
      
      const maxSnippetLength = 150;
      const truncatedSnippet = cleanedSnippet.length > maxSnippetLength ? 
        cleanedSnippet.substring(0, maxSnippetLength) + '...' : 
        cleanedSnippet;
      
      const decoder = document.createElement('div');
      decoder.innerHTML = truncatedSnippet;
      snippet.textContent = decoder.textContent;
      
      const meta = document.createElement('div');
      meta.className = 'lunr-result-meta';
      meta.textContent = doc.date || '';
      
      resultItem.appendChild(title);
      resultItem.appendChild(snippet);
      resultItem.appendChild(meta);
      
      resultsList.appendChild(resultItem);
    });
    
    resultsContainer.appendChild(resultsList);
  }
  
  searchButton.addEventListener('click', performSearch);
  
  searchInput.addEventListener('keyup', function(event) {
    if (event.key === 'Enter') {
      performSearch();
    }
  });
  
  searchInput.addEventListener('input', function(event) {
    event.stopPropagation();
  });
});
</script>Code language: HTML, XML (xml)

Test your search functionality

After you replace the code, save the page and test it on the frontend. Type something into the search bar that relates to content on your site and see if you get a result:

Testing search functionality on the frontend.

Also click on the result to ensure that it takes you to the page or post that’s showing.

Then try the search operators. Type the same query but add a * to then end of it and see what comes up:

Testing search functionality of search operator on the frontend.

Repeat again but put your query inside quotation marks. If everything looks like it’s working, then you can make your way to the last leg of the implementation.

Phase four: Update your live site 📤

Publishing the search page to your live site is an exciting moment and shouldn’t take you more than a minute or two if you already have everything set up from having followed my WordPress static site tutorial. From your wp-admin inside of Local:

  • Go back to Simply Static and check the Diagnostics option to make sure there are no issues.
  • If everything is fine, then tap on Generate:
Regenerating static site files after adding contact form to post.

Afterwards do the following:

On Mac: On Windows:

Open up Terminal and make your way to the directory (folder) that has your Python snippet. For example:

cd ~/Desktop/website-toolsCode language: JavaScript (javascript)

From inside the folder, run the execution script:

./update-website.sh

Use File Explorer to go to the folder that has your Python snippet. If you’re unsure, you can search for it – update-website.bat. This is assuming that you saved the file under that name as suggested in my static site tutorial. If not, then you can try searching for .bat, which will bring up all .bat files on your hard drive. After you find the file, double click it to execute it.

✋🤔 If you need more context, go to the static WordPress site tutorial and then come back here after you read it.

Wait a few minutes after you run the Python script. Then check your live website, but more importantly check the search page. Test it one final time so you know everything is still working and that’s it. You’re done. 🎉

Final thoughts 💭

Static WordPress sites come with a host of advantages – cost, speed, security – but they’re not without their limitations. Luckily, there are all sorts of ways to work around them if you’re willing to think creatively and put in a little bit of work.

Whether it’s adding a full-fledged search solution like we covered here or adding contact forms like I covered previously, you can have your cake and eat it too.

For search specifically, if your site ever grows beyond the 500-page mark where Lunr.js starts to show its limitations, Fuse.js makes an excellent alternative. It works differently (using fuzzy matching at search time rather than building an index upfront like you learned here), but it’s much more efficient for static sites with massive amounts of content.

Do you have any questions on how to add search to a static site? Let me know in the comments below. I’ll be happy to help.

Don’t forget to join our crash course on speeding up your WordPress site. Learn more below:

 
Yay! 🎉 You made it to the end of the article!
Martin Dubovic
Share:

0 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments

Or start the conversation in our Facebook group for WordPress professionals. Find answers, share tips, and get help from other WordPress experts. Join now (it’s free)!