
I finally decided to try [FlexSearch](https://github.com/nextapps-de/flexsearch) after noting its use in [DAIR.AI's Prompt Engineering Guide](/weblinks/2023/09/12/dairai-s-prompt-engineering-guide):

<style>
#search-box {
padding: 10px;
width: 300px;
}

#search-results a {
display: block;
padding: 5px;
text-decoration: none;
color: #333;
}

#search-results a:hover {
background-color: #f5f5f5;
}

</style>


<script src="/js/vendor/flexsearch.bundle.js"></script>
<div class="card col-sm-12 col-md-10 m-2 border mx-auto">
<div class="card-body">

<form class="mx-auto input-group search-bar search-query-fancy no-link" action="/search/" method="get" role="search" aria-label="Website Search" id="search-form">

<input type="text" class="form-control search-box" id="search-box" placeholder="Search..." name="q">
<button class="btn btn-outline-secondary" type="submit" aria-label="Submit Search">
            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-search" viewBox="0 0 16 16">
                <path d="M11.742 10.344a6.5 6.5 0 1 0-1.397 1.398h-.001c.03.04.062.078.098.115l3.85 3.85a1 1 0 0 0 1.415-1.414l-3.85-3.85a1.007 1.007 0 0 0-.115-.1zM12 6.5a5.5 5.5 0 1 1-11 0 5.5 5.5 0 0 1 11 0z"/>
            </svg>
        </button>
</form>

<div id="search-results" class="text-left"></div>

</div>
</div>



<script src="/js/search/flexsearch_implementation.js"></script>


<script>
  var posts = [
    {% for post in site.posts %}
      {
        "id": "{{ post.url | slugify }}",
        "type": "posts",
        "title": "{{ post.title | xml_escape }}",
        "author": "{{ post.author | xml_escape }}",
        "date": "{{ post.date | xml_escape }}",
        "category": "{{ post.category | xml_escape }}",
        "tags": "{{ post.tags | xml_escape | replace: '&quot;', '' }}",
        "content": {{ post.content | strip_html | jsonify }},
        "snippet": {{ post.snippet | markdownify | jsonify }},
        "url": "{{ post.url | xml_escape }}",
        "snippet_image": "{{ post.snippet_image | xml_escape }}",
        "snippet_image_alt": "{{ post.snippet_image_alt | xml_escape }}",
        "snippet_image_class": "{{ post.snippet_image_class | xml_escape }}"
      }
      {% unless forloop.last %},{% endunless %}
    {% endfor %}
  ];

{% comment %}
This block of code generates an array of pages (excluding the ones with layout == "none" 
and those with lunr.js set to "noindex" (i.e. "lunrjs: noindex") in the front matter) to be indexed by lunr.js. 
{% endcomment %}

{% assign diss_url = "diss/" %}
{% assign shortcuts_url = "shortcuts/" %}
{% assign courses_url = "courses/" %}

var pages = [
  {% for page in site.pages %}
    {% comment %} Skip the page if it's marked with 'noindex' or if its layout is set to 'none' {% endcomment %}
    {% if page.lunrjs != 'noindex' and page.layout != 'none' %}
    {
      "id": "{{ page.url | slugify }}",
      
      {% comment %}
      Set the type according to the URL.
      Pages under "/diss/" will be marked as 'diss', 
      and those under "/shortcuts/" will be marked as 'shortcuts'.
      {% endcomment %}
      "type": 
        {% if page.url contains diss_url %}
          "diss"
        {% elsif page.url contains shortcuts_url %}
          "shortcuts"
        {% elsif page.url contains courses_url %}
          "courses"
        {% else %}
          "pages"
        {% endif %},

      "date": "{{ page.date | xml_escape }}",
      "title": 
        {% if page.url == "/feed.xml" %}
          "feed.xml"
        {% elsif page.url == "/redirects.json" %}
          "redirects.json"
        {% else %}
          "{{ page.title | xml_escape }}"
        {% endif %},
      "tags": "{{ page.tags | xml_escape | replace: '&quot;', '' }}",
      "content": {{ page.content | strip_html | jsonify }},
      "snippet": {{ page.snippet | markdownify | jsonify }},
      "url": "{{ page.url | xml_escape }}",
      "snippet_image": "{{ page.snippet_image | xml_escape }}",
      "snippet_image_alt": "{{ page.snippet_image_alt | xml_escape }}",
      "snippet_image_class": "{{ page.snippet_image_class | xml_escape }}"
    }
    {% unless forloop.last %},{% endunless %}
    {% endif %}
  {% endfor %}
];

var externals = [
  {% for external in site.data.external_pages %}
    {
      "id": "{{ external.url | slugify }}",
      "type": "{{ external.type }}",
      "date": "{{ external.date | xml_escape }}",
      "title": "{{ external.title }}",
      "tags": "{{ external.tags | xml_escape | replace: '&quot;', '' }}",
      "content": {{ external.content | strip_html | jsonify }},
      "snippet": {{ external.snippet | markdownify | jsonify }},
      "url": "{{ external.url | xml_escape }}",
      "snippet_image": "{{ external.snippet_image | xml_escape }}",
      "snippet_image_alt": "{{ external.snippet_image_alt | xml_escape }}",
      "snippet_image_class": "{{ external.snippet_image_class | xml_escape }}"
    }
    {% unless forloop.last %},{% endunless %}
  {% endfor %}
];


  window.store = [...posts, ...pages, ...externals];

</script>

<script>
  document.getElementById('search-form').onsubmit = function() {
    var searchBox = document.getElementById('search-box');
    if (searchBox.value === 'similar:') {
      searchBox.value = 'similar:' + window.location.pathname;
    }
    if (searchBox.value === 'backlinks:') {
      searchBox.value = 'backlinks:' + window.location.pathname;
    }
    return true; // make sure the form still submits
  };

  document.addEventListener('DOMContentLoaded', () => {
    const form = document.getElementById('search-form');
    form.onsubmit = () => handleBangs(form); 
  });

</script>

