diff --git a/content/_index.md b/content/_index.md
index 95d0241..16c3057 100644
--- a/content/_index.md
+++ b/content/_index.md
@@ -12,52 +12,7 @@ description: 'The fast-loading recipe site with cooking only and no ads.'
-
+
## Newest Recipes
diff --git a/static/js/search.js b/static/js/search.js
new file mode 100644
index 0000000..c5631ad
--- /dev/null
+++ b/static/js/search.js
@@ -0,0 +1,44 @@
+// @license magnet:?xt=urn:btih:5ac446d35272cc2e4e85e4325b146d0b7ca8f50c&dn=unlicense.txt Unlicense
+
+document.addEventListener("DOMContentLoaded", () => {
+ for (e of document.getElementsByClassName("js-only")) {
+ e.classList.remove("js-only");
+ }
+
+ const recipes = document.querySelectorAll("#artlist li");
+ const search = document.getElementById("search");
+ const oldheading = document.getElementById("newest-recipes");
+ const clearSearch = document.getElementById("clear-search");
+ const artlist = document.getElementById("artlist");
+
+ search.addEventListener("input", () => {
+ // grab search input value
+ const searchText = search.value.toLowerCase().trim().normalize('NFD').replace(/\p{Diacritic}/gu, "");
+ const searchTerms = searchText.split(" ");
+ const hasFilter = searchText.length > 0;
+
+ artlist.classList.toggle("list-searched", hasFilter);
+ oldheading.classList.toggle("hidden", hasFilter);
+
+ // for each recipe hide all but matched
+ recipes.forEach(recipe => {
+ const searchString = `${recipe.textContent} ${recipe.dataset.tags}`.toLowerCase().normalize('NFD').replace(/\p{Diacritic}/gu, "");
+ const isMatch = searchTerms.every(term => searchString.includes(term));
+
+ recipe.hidden = !isMatch;
+ recipe.classList.toggle("matched-recipe", hasFilter && isMatch);
+ })
+ })
+
+ clearSearch.addEventListener("click", () => {
+ search.value = "";
+ recipes.forEach(recipe => {
+ recipe.hidden = false;
+ recipe.classList.remove("matched-recipe");
+ })
+
+ artlist.classList.remove("list-searched");
+ oldheading.classList.remove("hidden");
+ })
+})
+// @license-end