
Running a static WordPress site comes with serious perks—faster load times, better security, and fewer hosting headaches. But it’s not without its quirks. One major downside? No built-in search functionality.
That’s because WordPress’s native search is powered by PHP and queries the database. Static sites don’t use either.
But don’t worry—you can add a fully functional, client-side search feature using Lunr.js, a free JavaScript library built just for this sort of challenge.
🔍 What is Lunr.js and Why It’s Ideal for Static WordPress Sites
Lunr.js is a lightweight JavaScript-based search engine that runs entirely in the browser. It doesn’t need server-side code, databases, or even API calls—perfect for static websites. You build a search index as a JSON file, and Lunr.js uses it to match keywords and return results—all client-side.

It’s fast, free, and requires no third-party service. That means no extra hosting costs or maintenance.
Before jumping in, it’s good to know what Lunr.js does well—and where it might not be the perfect fit.
⚖️ Pros and Cons of Using Lunr.js
✅ What You’ll Love:
- Built-in relevance scoring.
- Handles typos with fuzzy matching.
- Supports stemming (e.g., “run” matches “running”).
🚫 What You’ll Trade Off:
- Doesn’t understand natural language queries.
- Can’t process advanced search logic (though wildcard and exact-match operators are supported).
💡 Performance Tip:
Lunr is ideal for sites with fewer than 500 pages. Above that, index size and memory use may become issues. For large-scale static sites, consider alternatives like Fuse.js.
🔧 Step 1: Prep Your Dev Environment
Before anything else, gather your tools:
- A local WordPress install (e.g., via Local by Flywheel).
- Simply Static plugin.
- A text/code editor like VS Code or Sublime Text.
- Terminal (macOS/Linux) or Command Prompt (Windows).
- Lunr.js (linked via CDN or downloaded).
⚠️ This tutorial uses a block-based theme (like Neve FSE), but works with classic themes too—with only minor tweaks.
🧪 Step 2: Add Lunr.js to Your Site’s Header
- Open your local WordPress site’s admin.
- Go to Appearance → Editor (for block themes) or Appearance → Theme File Editor (for classic themes).

- Locate the Header template part or file.

- Add the following inside the
<head>
section via a Custom HTML block or directly in the theme file:

<script src="https://unpkg.com/lunr/lunr.js"></script>
Click Save when done.
📄 Step 3: Build a Search Page in WordPress
- Create a new page and name it something like Search.
- Add a Group block and insert:
- A Heading block (“Search This Site”)
- A Paragraph block (e.g., “Start typing below to find content.”)

- A Custom HTML block with the following:
<div class="lunr-search-container">
<input id="lunr-search-input" placeholder="Type to search..." />
<button id="lunr-search-button">Search</button>
<div id="lunr-search-results"></div>
</div>
- Add a note below the input field with this HTML block:
<div class="search-tips">
<small><strong>Tips:</strong> Use * for wildcards, and " " for exact phrases.</small>
</div>
- Add one more Custom HTML block for JavaScript:
<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>
- For CSS:
<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>
🧱 Step 4: Create the Search Index
You’ll now generate a .json
file that Lunr can use to search your content.
Build a Custom Plugin to Export Your Posts:
- In your local site’s
wp-content/plugins/
, create a new folder:lunr-index-generator
- Inside it, create a file:
lunr-index-generator.php
- Paste this starter plugin code:
<?php
/*
Plugin Name: Lunr Index Generator
Description: Exports post data to JSON for Lunr.js
*/
add_action('admin_menu', function() {
add_management_page('Lunr Search Index', 'Lunr Index', 'manage_options', 'lunr-index', function() {
echo '<div class="wrap"><h1>Lunr Index</h1>';
if ($_POST['generate']) {
$posts = get_posts(['numberposts' => -1, 'post_status' => 'publish']);
$data = [];
foreach ($posts as $post) {
$data[] = [
'id' => $post->ID,
'title' => $post->post_title,
'content' => strip_tags($post->post_content),
'url' => get_permalink($post->ID),
];
}
file_put_contents(get_stylesheet_directory() . '/lunr-search-index.json', json_encode($data));
echo '<p><strong>Index created!</strong></p>';
}
echo '<form method="post"><input type="submit" name="generate" value="Generate Index" class="button button-primary"></form>';
echo '</div>';
});
});
- Go to Plugins → Installed Plugins and activate your new plugin.

- Then head to Tools → Lunr Index and click Generate Index.

Your new JSON file will appear in your theme folder.
⚙️ Step 5: Add the Index to Simply Static
To include this JSON file when exporting your static site:
- In wp-admin, go to Simply Static → Settings → Additional Files.
- Add the path to your JSON index, like:
/wp-content/themes/your-theme/lunr-search-index.json
📲 Step 6: Add the Real Search JavaScript
Head back to your Search page in WordPress.
Find the bottom HTML block (where you left space for JS) and paste:
<script>
document.getElementById('lunr-search-button').addEventListener('click', function() {
fetch('/wp-content/themes/YOUR-THEME-NAME/lunr-search-index.json')
.then(res => res.json())
.then(data => {
const idx = lunr(function () {
this.ref('id');
this.field('title');
this.field('content');
data.forEach(doc => this.add(doc));
});
const query = document.getElementById('lunr-search-input').value;
const results = idx.search(query);
const output = results.map(r => {
const item = data.find(d => d.id == r.ref);
return `<p><a href="${item.url}">${item.title}</a></p>`;
}).join('') || '<p>No results found.</p>';
document.getElementById('lunr-search-results').innerHTML = output;
});
});
</script>
🔁 Replace
YOUR-THEME-NAME
with your actual theme directory name.
Click Update to save your page.
🚀 Step 7: Regenerate Your Static Site
Finally, regenerate your site’s static version:
- Go to Simply Static → Generate.
- Wait for the export to complete.
- Upload to your host or run your update script.
Visit the live search page and test it. Try different keywords, partial matches (design*
), and quoted phrases ("static WordPress"
).
✅ Final Thoughts
Static WordPress sites are blazing fast, but sometimes too simple. With Lunr.js, you can add a powerful search feature—without touching PHP or paying a dime.
If your site ever grows too big for Lunr to handle, Fuse.js is a great next-level option.
Got questions about adding search to your static site? Drop them in the comments below—I’m here to help.
0 Comments