Build a GitHub-Style Search Filter Box

Build a GitHub-style filter box that narrows a list as you type.

Introduction

30 Second Summary

Long lists become frustrating when a basic search field treats every word the same. Finding one record gets slower when you need to search by a name, category, or year.

In this project, you will build a GitHub-style search box on one static HTML page. Your JavaScript uses the parsed search to narrow a list of about twenty records as you type.

What You'll Build

You type artist:"Aphex Twin" into the rich-input field to watch unrelated rows disappear while matching records stay on screen.

By the end of this project, you'll have:

  • A free-text search that finds records by their visible details. Structured filters let you target fields such as artist, label, or year.
  • A suggestion dropdown that offers your own filter keys as you type. The browser console shows the parsed search object behind each query.
  • A responsive record list that shrinks as the query becomes more specific. A clear empty state appears when no records match.
  • Secret Mission: An optional challenge to push your skills further.

Do I need anything before starting?

You need a text editor, a modern browser, and basic JavaScript knowledge. The project runs as one local HTML file with no account, server, or build step.

The project costs nothing to run.

Before We Start

This project lives in one HTML file. You need a reliable place to write that file before the filtering work begins.

A code editor handles the page source. A modern browser with Developer Tools gives you a live view of the page structure.

In this step, get ready to:
  • Confirm your code editor opens correctly.
  • Confirm your modern web browser opens correctly.
  • Confirm Developer Tools are available in your browser.
Confirm your code editor

Your code editor is where you will write the page structure and filtering logic. Opening it now confirms your workspace is ready before any project files exist.

  • Press Cmd+Space on macOS or the Windows key on Windows to open your system search.
  • Search for the code editor you plan to use.
  • Select the editor from the search results.

You should see the editor's main window. This confirms the editor is available for the project.

Cannot Find a Code Editor?

  • Choose a code editor from its official website.
  • Install the editor using its recommended options.
  • Repeat the system search after installation.

Help me choose and install a code editor for a static HTML and JavaScript project.

Confirm your browser tools

The browser displays your page as a visitor sees it. Its developer workspace helps you inspect the HTML behind that view.

  • Press Cmd+Space on macOS or the Windows key on Windows to open your system search.
  • Search for a modern web browser installed on your computer.
  • Select the browser from the search results.

Before the final check, what do you expect a browser's developer workspace to reveal?

  • Open the browser's main menu.
  • Choose the option that opens Developer Tools.

One area lets you inspect page structure. Another area shows browser messages.

Why Developer Tools Matter

Developer Tools connects what you write to what the browser renders. Later, its message area shows the parsed filter object as you type.

Browser Tools Unavailable?

  • Confirm you are using a desktop browser with developer features.
  • Install a current desktop browser from its official website if you do not have one.
  • Check the browser's official help page for its Developer Tools instructions.

Help me open Developer Tools in my desktop browser.

Your editor opens correctly. Your browser can expose the page details you will debug.

Next, you will create index.html. The unfiltered record list becomes your first visible result.

Create the Record List

A search filter needs something concrete to narrow down. This step creates the collection that every later query will test.

A standalone HTML page gives the later filter a stable set of records to test. The same file also holds a hidden message for searches with no matches.

In this step, get ready to:
  • Create index.html on your Desktop.
  • Add twenty record rows plus a hidden empty state.
  • Render the full unfiltered list in your browser.
Create the HTML file

HTML data attributes attach filterable values to each row. The visible text gives you a list you can verify before any search logic exists.

  • Press Cmd+Space on macOS or the Windows key on Windows to open system search.
  • Type the name of your code editor into the search bar.
  • Press Enter to open your code editor.
  • Create a blank file from your code editor's file menu.
  • Choose the save action from the same menu.
  • Select Desktop as the save location.
  • Enter index.html as the file name.
  • Confirm the save.

The empty index.html file is ready for your record page.

  • Fill index.html with the complete record page by pasting this code:
<!doctype html>
<html lang="en">
<head>
  <!-- Keep the page portable without build tools. -->
  <meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Record Finder</title>
</head>
<body><main>
  <h1>Record Finder</h1>
  <!-- Each row stores fields that later filters can match. --><ul id="record-list">
    <li class="record-row" data-artist="Aphex Twin" data-label="Orbit" data-year="1992"><strong>Signal Archive</strong> · Aphex Twin · Orbit · 1992</li>
    <li class="record-row" data-artist="Mira Sol" data-label="Northstar" data-year="2001"><strong>Night Geometry</strong> · Mira Sol · Northstar · 2001</li>
    <li class="record-row" data-artist="Glass Harbor" data-label="Drift" data-year="1998"><strong>Salt Air</strong> · Glass Harbor · Drift · 1998</li>
    <li class="record-row" data-artist="Northbound" data-label="Canvas" data-year="2015"><strong>Parallel Lines</strong> · Northbound · Canvas · 2015</li>
    <li class="record-row" data-artist="Echo Vale" data-label="Lantern" data-year="2007"><strong>Soft Machines</strong> · Echo Vale · Lantern · 2007</li>
    <li class="record-row" data-artist="Mira Sol" data-label="Northstar" data-year="2004"><strong>Paper Moons</strong> · Mira Sol · Northstar · 2004</li>
    <li class="record-row" data-artist="Paper Satellites" data-label="Orbit" data-year="1992"><strong>Slow Bloom</strong> · Paper Satellites · Orbit · 1992</li>
    <li class="record-row" data-artist="Atlas Bloom" data-label="Canvas" data-year="2015"><strong>Low Tide</strong> · Atlas Bloom · Canvas · 2015</li>
    <li class="record-row" data-artist="Quiet Current" data-label="Drift" data-year="2020"><strong>Afterimage</strong> · Quiet Current · Drift · 2020</li>
    <li class="record-row" data-artist="Neon Orchard" data-label="Lantern" data-year="2018"><strong>Static Gardens</strong> · Neon Orchard · Lantern · 2018</li>
    <li class="record-row" data-artist="Silver Static" data-label="Orbit" data-year="1997"><strong>Hollow Light</strong> · Silver Static · Orbit · 1997</li>
    <li class="record-row" data-artist="Rowan Grey" data-label="Northstar" data-year="2001"><strong>Arcade Weather</strong> · Rowan Grey · Northstar · 2001</li>
    <li class="record-row" data-artist="Lunar Arcade" data-label="Canvas" data-year="2015"><strong>Deep Blue</strong> · Lunar Arcade · Canvas · 2015</li>
    <li class="record-row" data-artist="Blue Meridian" data-label="Drift" data-year="1994"><strong>Morning Hours</strong> · Blue Meridian · Drift · 1994</li>
    <li class="record-row" data-artist="The Daylights" data-label="Lantern" data-year="1985"><strong>Open Windows</strong> · The Daylights · Lantern · 1985</li>
    <li class="record-row" data-artist="Sora Lane" data-label="Northstar" data-year="2007"><strong>Velvet Lines</strong> · Sora Lane · Northstar · 2007</li>
    <li class="record-row" data-artist="Velvet Transit" data-label="Orbit" data-year="2022"><strong>Ash and Gold</strong> · Velvet Transit · Orbit · 2022</li>
    <li class="record-row" data-artist="Cinder House" data-label="Canvas" data-year="1979"><strong>Wildflowers</strong> · Cinder House · Canvas · 1979</li>
    <li class="record-row" data-artist="Nia Hart" data-label="Drift" data-year="2019"><strong>Current Affairs</strong> · Nia Hart · Drift · 2019</li>
    <li class="record-row" data-artist="Open Circuit" data-label="Lantern" data-year="2021"><strong>Last Transmission</strong> · Open Circuit · Lantern · 2021</li>
  </ul><!-- The filtering step reveals this message when no rows match. --><p id="empty-state" hidden>No records match your filters.</p></main></body></html>

What Does This HTML Do?

  • The data-artist attribute stores the artist that a future filter can match.
  • The data-label attribute stores each record's label.
  • The data-year attribute stores each record's release year.
  • The hidden attribute keeps the empty-state message out of sight while records are available.
  • Save index.html from your code editor's file menu.
  • Confirm that index.html appears in your editor's file list.

Your record page now has a stable home on your Desktop.

File Name Looks Wrong?

A missing file name means the save did not finish. Repeat the save action with Desktop as the location.

Confirm that the file ends with .html. A .txt ending prevents the browser from treating it as a web page.

Help me fix my file setup.

Open the unfiltered record list

Opening the static file in a browser gives you a baseline for every later filter. All twenty rows should render before the search field exists.

  • Press Cmd+Space on macOS or the Windows key on Windows to open system search.
  • Type Finder on macOS or File Explorer on Windows.
  • Press Enter to open the file manager.
  • Select the Desktop folder.

Before you open the file, how many record rows do you expect the browser to render?

  • Open index.html by double-clicking the file.

That baseline is locked in: your browser shows the Record Finder heading above twenty unfiltered rows. The empty-state message remains hidden.

Page Missing Some Records?

Visible markup text usually means the file has the wrong extension. Confirm that the name ends with index.html.

A shorter list usually means part of the code was missed. Compare your file with the complete version below.

Help me troubleshoot my record list.

✔️ Awesome, I've got everything!

Your browser is showing the complete unfiltered record list.

ⓧ I'd like to double check the full code

<!doctype html>
<html lang="en">
<head>
  <!-- Keep the page portable without build tools. -->
  <meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Record Finder</title>
</head>
<body><main>
  <h1>Record Finder</h1>
  <!-- Each row stores fields that later filters can match. --><ul id="record-list">
    <li class="record-row" data-artist="Aphex Twin" data-label="Orbit" data-year="1992"><strong>Signal Archive</strong> · Aphex Twin · Orbit · 1992</li>
    <li class="record-row" data-artist="Mira Sol" data-label="Northstar" data-year="2001"><strong>Night Geometry</strong> · Mira Sol · Northstar · 2001</li>
    <li class="record-row" data-artist="Glass Harbor" data-label="Drift" data-year="1998"><strong>Salt Air</strong> · Glass Harbor · Drift · 1998</li>
    <li class="record-row" data-artist="Northbound" data-label="Canvas" data-year="2015"><strong>Parallel Lines</strong> · Northbound · Canvas · 2015</li>
    <li class="record-row" data-artist="Echo Vale" data-label="Lantern" data-year="2007"><strong>Soft Machines</strong> · Echo Vale · Lantern · 2007</li>
    <li class="record-row" data-artist="Mira Sol" data-label="Northstar" data-year="2004"><strong>Paper Moons</strong> · Mira Sol · Northstar · 2004</li>
    <li class="record-row" data-artist="Paper Satellites" data-label="Orbit" data-year="1992"><strong>Slow Bloom</strong> · Paper Satellites · Orbit · 1992</li>
    <li class="record-row" data-artist="Atlas Bloom" data-label="Canvas" data-year="2015"><strong>Low Tide</strong> · Atlas Bloom · Canvas · 2015</li>
    <li class="record-row" data-artist="Quiet Current" data-label="Drift" data-year="2020"><strong>Afterimage</strong> · Quiet Current · Drift · 2020</li>
    <li class="record-row" data-artist="Neon Orchard" data-label="Lantern" data-year="2018"><strong>Static Gardens</strong> · Neon Orchard · Lantern · 2018</li>
    <li class="record-row" data-artist="Silver Static" data-label="Orbit" data-year="1997"><strong>Hollow Light</strong> · Silver Static · Orbit · 1997</li>
    <li class="record-row" data-artist="Rowan Grey" data-label="Northstar" data-year="2001"><strong>Arcade Weather</strong> · Rowan Grey · Northstar · 2001</li>
    <li class="record-row" data-artist="Lunar Arcade" data-label="Canvas" data-year="2015"><strong>Deep Blue</strong> · Lunar Arcade · Canvas · 2015</li>
    <li class="record-row" data-artist="Blue Meridian" data-label="Drift" data-year="1994"><strong>Morning Hours</strong> · Blue Meridian · Drift · 1994</li>
    <li class="record-row" data-artist="The Daylights" data-label="Lantern" data-year="1985"><strong>Open Windows</strong> · The Daylights · Lantern · 1985</li>
    <li class="record-row" data-artist="Sora Lane" data-label="Northstar" data-year="2007"><strong>Velvet Lines</strong> · Sora Lane · Northstar · 2007</li>
    <li class="record-row" data-artist="Velvet Transit" data-label="Orbit" data-year="2022"><strong>Ash and Gold</strong> · Velvet Transit · Orbit · 2022</li>
    <li class="record-row" data-artist="Cinder House" data-label="Canvas" data-year="1979"><strong>Wildflowers</strong> · Cinder House · Canvas · 1979</li>
    <li class="record-row" data-artist="Nia Hart" data-label="Drift" data-year="2019"><strong>Current Affairs</strong> · Nia Hart · Drift · 2019</li>
    <li class="record-row" data-artist="Open Circuit" data-label="Lantern" data-year="2021"><strong>Last Transmission</strong> · Open Circuit · Lantern · 2021</li>
  </ul><!-- The filtering step reveals this message when no rows match. --><p id="empty-state" hidden>No records match your filters.</p></main></body></html>

Your baseline list is ready in the editor. Next, you'll add the search field above it.

Add the Rich Search Input

Your record catalog is already visible in the browser. Its rows give the search interface something concrete to sit above.

A Web Component only works after the browser loads the JavaScript that defines it. This step connects the rich-input component to your page so the browser can render the new field.

In this step, get ready to:
  • Load the pinned browser module for the rich input.
  • Place the custom element above the record list.
  • Verify that the search field renders while every record remains visible.
Load the rich input module

The browser module registers rich-input as a valid custom element. Pinning the import to version 1.2.2 keeps your page tied to the component code you test today.

Why Use a CDN Import?

A CDN lets your static page load the component directly from the web. This keeps the project inside one HTML file without adding a build step.

  • In index.html, locate the closing </head> tag.
  • Add the module import immediately before that tag:
<!-- Register the pinned custom element in the browser. -->
<script type="module" src="https://cdn.jsdelivr.net/npm/rich-input@1.2.2/index.js"></script>

What Does This Import Do?

The script downloads the browser-ready component code. The type="module" attribute tells the browser to load it as a JavaScript module.

Once the module runs, the browser knows how to turn a <rich-input> tag into an interactive search field.

Place and verify the search field

The module supplies the component behavior. The custom element marks where the search field belongs on your page.

  • In index.html, locate the element that contains your hardcoded record rows.
  • Add the rich input immediately above that element:
<!-- Mount the rich search field above the records. -->
<rich-input placeholder="Search music catalog..."></rich-input>

What Does This Element Do?

The <rich-input> tag creates the visible search control. Its placeholder attribute supplies the hint shown inside the empty field.

The component sits above your existing records without changing them. Your list remains available for the filtering logic you add later.

  • Save index.html.

Your prediction: picture what should appear above the list when the browser recognizes the custom element.

  • Switch back to the browser tab from earlier.
  • Reload the page.

You should see a rich search field above the same unfiltered record list. The list should still show approximately twenty records.

Search Field Missing?

  • Confirm that the module import sits before the closing </head> tag.
  • Check that both <rich-input> tags use the same spelling.
  • Confirm that your browser has an internet connection so it can download the module.
  • Reload the page after saving index.html.

Help me find why the rich search field is not rendering above my record list.

That is the component mounted successfully. Your static catalog now has a rich search field while every record remains visible.

The input is mounted above your catalog. Next, you will declare the artist, label, and year filter keys.

Declare Filter Keys

Your rich search field now renders above the complete record list. Its suggestion menu still needs vocabulary that matches the records on your page.

Nested HTML datalists configure the filter keys for this Web Component. In this step, you will declare artist, label, and year as the available keys.

In this step, get ready to:
  • Declare the artist filter key.
  • Declare the label filter key.
  • Declare the numeric year filter key.
Configure the filter vocabulary

Each datalist nested inside rich-input declares one structured filter. Its id becomes the key that the field suggests.

  • In index.html, locate the closing </rich-input> tag.
  • Add the three filter definitions immediately above that tag by pasting this code:
  <!-- Define the filter keywords offered by the search field. -->
  <datalist id="artist" label="Artist"></datalist>
  <datalist id="label" label="Label"></datalist>
  <datalist id="year" label="Year" data-type="number"></datalist>

What does this markup do?

  • The id attribute supplies the text before the colon in a structured filter.
  • The label attribute supplies the readable name shown by the suggestion menu.
  • The data-type="number" attribute tells the field that year expects numeric values.
  • The empty datalists declare keyword suggestions without adding value suggestions.
  • Save index.html.
  • Switch back to the browser from the previous step.
  • Reload the page.

You should still see the rich search field above the complete record list. This confirms the new configuration preserved the page structure.

Did the search field disappear?

  • Confirm that all three datalist elements sit before the closing </rich-input> tag.
  • Check that every opening <datalist> tag has a matching closing tag.

Help me troubleshoot why the rich search field disappeared after I added its datalists.

✔️ Awesome, I've got everything!

Your three datalists are nested inside the rich search field. The page is ready for the suggestion check.

ⓧ I'd like to double check the full code

Keep the existing module import, record rows, and empty state unchanged. The configuration inside your existing rich-input element should include this section:

  <!-- Define the filter keywords offered by the search field. -->
  <datalist id="artist" label="Artist"></datalist>
  <datalist id="label" label="Label"></datalist>
  <datalist id="year" label="Year" data-type="number"></datalist>

These three definitions add the required suggestion vocabulary while preserving the unfiltered record list.

Test the suggestion menu

Keyword suggestions respond to the beginning of the active token. Testing each first letter proves that every configured key is available.

Before you test the field, which configured key do you expect to see after entering a?

  • Select the rich search field.
  • Type a.

You should see artist: in the suggestion dropdown. The full record list remains visible.

  • Press Backspace to remove a.
  • Type l.

You should see label: in the suggestion dropdown. The record rows remain unchanged.

  • Press Backspace to remove l.
  • Type y.

You should see year: in the suggestion dropdown. The complete record list stays visible because filtering is added later.

Are one or more suggestions missing?

  • Match each id exactly to artist, label, or year.
  • Reload the page after saving index.html.
  • Clear the existing query before testing another first letter.

Help me troubleshoot missing filter-key suggestions.

That is the search vocabulary locked in. Your field now guides people toward all three structured filters.

Your field can now suggest the structure of a search. Next, you will inspect the parsed query that structure produces.

Inspect Parsed Search Values

Your search field now suggests the three filter keys you configured. The full list stays visible because the page does not use the parsed query yet.

The rich input is a Web Component that emits an input event whenever its value changes. This step captures that event so you can inspect the query object before using it to control the records.

In this step, get ready to:
  • Listen for changes from the rich input.
  • Inspect the parsed object in the browser console.
Log the parsed search object

The getParsedQuery() method turns the current search string into data your JavaScript can read. An event listener lets you request fresh parsed data after every change.

  • In index.html, find the closing </body> tag.
  • Connect the search field to the console by pasting this block immediately above the closing tag:
<script>
  // Find the rich search field already rendered on the page.
  const searchInput = document.querySelector('rich-input');

  // Log the parsed query every time its value changes.
  searchInput.addEventListener('input', () => {
    console.log(searchInput.getParsedQuery());
  });
</script>

What Does This Listener Do?

  • The searchInput variable holds the existing rich-input element.
  • The input event runs the callback whenever the search value changes.
  • The getParsedQuery() method returns the structured search object.
  • The console.log() call displays that object for inspection.
  • Save index.html.
  • Switch back to the browser from earlier.
  • Reload the page.

You should still see the rich search field above the full record list. This confirms that the new script loads without disrupting the page.

Did the Search Field Stop Working?

Check that the new <script> block sits below the rich-input element. Make sure it remains above </body>.

Save index.html before reloading the page.

Ask for help with the listener..

Inspect a structured query

The parsed object separates ordinary search words from recognized filters. This structure gives your filtering logic a clear value for each kind of match.

  • Open Developer Tools from your browser's menu.
  • Choose the console panel.

Before you type the test query, where do you expect the artist name to appear in the parsed object?

  • Enter artist:"Aphex Twin" in the search field.
  • Expand the latest object in the console.

What Should You See?

  • The raw property contains the complete query.
  • The text property contains the free-text portion.
  • The keywords property stores Aphex Twin under artist.
  • The tokens property contains details about the parsed pieces.

Every record should remain visible. This step only inspects the data produced by the search field.

Nothing Appearing in the Console?

Reload the page after saving index.html. Type a new character after the console is open so the input event fires again.

Check that searchInput uses the same spelling in the declaration and the listener.

Ask for help inspecting the event..

Your console now proves that the search field produces structured data. Next, you'll use that object to control which records stay visible.

Filter the Record List

Your rich-input custom element already turns each query into structured data. The record list still ignores that result.

This step connects the parsed query to each record row. One filter pass controls the rows plus the empty state.

In this step, get ready to:
  • Match free text against each record's searchable content.
  • Apply structured filters to the corresponding record metadata.
  • Control record visibility plus the empty state.
Match queries against records

Filtering starts with separate rules for the parsed object's text value plus its keywords value. Free text checks each row's searchable content.

Each structured key checks only its corresponding metadata. A row qualifies when every populated part matches.

  • In index.html, find the existing input-event listener that currently logs the parsed search object.
  • Replace its console-only body with one filter pass that computes a match result for every existing record row.

How Should the Filter Pass Work?

  • Call getParsedQuery() once to capture the current query.
  • Normalize the parsed text value before comparing it with row content.
  • Read the artist filter from the parsed keywords object.
  • Read the label filter from the same object.
  • Read the year filter from the same object.
  • Treat a missing structured filter as an empty filter list.
  • Keep a row eligible only when its active checks pass.
  • Save index.html.
  • Return to the browser from earlier.
  • Refresh the page.

Before you test this filter pass, which records do you expect to remain for an artist-specific query?

  • Enter artist:"Aphex Twin" in the rich input.

You should see only records whose artist data matches Aphex Twin.

Rows Are Not Narrowing?

Confirm that the filter pass runs inside the existing input listener. Make sure it calls getParsedQuery() for the latest value.

Compare normalized query text with normalized row data. Differences in letter case can otherwise block valid matches.

Help me debug the record-matching logic.

Control row and empty-state visibility

Visibility turns each match result into a page change. The existing empty state covers the zero-match case.

  • Extend the same filter pass with visibility updates for every row plus the existing empty state.
  • Save index.html.
  • Return to the browser.
  • Refresh the page.

What Controls the Empty State?

Each matching row stays visible. Each nonmatching row becomes hidden.

The empty state becomes visible when the match count reaches zero. Any positive match count keeps it hidden.

Before you try a zero-match search, do you expect any record rows to remain visible?

  • Replace the current query with zzzzzz.

You should see the empty-state message with every record row hidden.

  • Click the clear button inside the rich input.

You should see the full record list return. The empty-state message should disappear.

Empty State Stuck on Screen?

Calculate the match count after evaluating the complete row collection. Use that final count to control the empty state.

Confirm that clearing the query makes every row eligible again.

Help me fix the empty-state visibility.

Test the full filter loop

A reliable filter proves each matching path independently. The final pass covers free text plus every declared structured key.

Before this final check, do you expect each structured key to search every field or only its corresponding metadata?

  • Enter a distinctive word from one visible record title.

You should see only rows whose searchable content includes that word.

  • Replace the free-text query with artist:"Aphex Twin".

You should see only records with Aphex Twin in their artist metadata.

  • Replace the artist query with label:.
  • Select one label value from the suggestion dropdown.

You should see only records with the selected label in their label metadata.

  • Replace the label query with year:.
  • Select one year value from the suggestion dropdown.

You should see only records with the selected year in their year metadata.

  • Replace the year query with zzzzzz.

You should see the empty-state message with no record rows visible.

  • Clear the search field.

You should see the complete list of approximately twenty records again. The empty state should be hidden.

That completes the search loop. Your page now narrows the record list as you type plus recovers cleanly when you clear the query.

Secret mission

Build a Search Regression Checklist

Turn your finished search page into a small quality assurance exercise. Test quoted filters plus mixed searches. Confirm the empty state and the full-list reset.

Clean Up Your Resources

Clean Up Your Resources

Choose whether to keep your page ready, pause your testing session, or remove the project entirely. This project is a local static HTML page, so keeping it has no ongoing cost.

Resources you used:

  • Local index.html file containing the completed search page.

Keep everything running

No action is needed. Choose this option if you want to keep testing the filtered record list or publish the page later.

  • Keep index.html in its current location.
  • Leave the page open in the browser if you plan to continue testing it now.

Pause - I'll come back to this later

Pausing closes the active browser view while preserving your work. The page remains ready to reopen from index.html.

  • Switch back to the browser tab from earlier.
  • Close the tab.
  • Keep index.html in its current location.

Delete - I don't want to use this again

Deleting removes the local page you built. Your browser and code editor remain installed.

Your Finished Page Will Be Removed

This action deletes your completed search page. Keep a copy somewhere else first if you want to reuse the filtering code.

  • Switch back to the code editor from earlier.
  • Find index.html in the editor's file sidebar.
  • Use the file's context menu to delete index.html.
  • Confirm the deletion if your editor asks.
  • Check that index.html no longer appears in the file sidebar.
  • Close the browser tab that displayed the page.

Nice Work!

Nice Work!

Fantastic work! Your static music list now responds to free text plus structured artist, label, and year filters.

You've learned how to:

  • Mount a rich custom element above a hardcoded record list.
  • Configure filter suggestions for artist, label, and year.
  • Turn the parsed search object into live row filtering. Your page restores every record when the field is cleared. It shows an empty state when no record matches.
  • Complete an optional Secret Mission to push your structured filtering skills further.

You now have a single index.html file that works without a build step. It is ready for any static host.

Ready to quiz yourself?