Search Autocomplete — <mv-search-autocomplete>

Storefront search with autocomplete: on focus, recent searches (localStorage, clearable) and trending chips; while typing (debounced, stale requests aborted, loading indicator), suggestions with the query highlighted regardless of accents, categories with counts, products with thumbnail and price (Intl, strikethrough compare-at), “See all 42 results for ‘sweater’”; “No results” state; keyboard shortcut; async source hook or local JSON catalog.

CategoryForms
TypeWeb Component (<mv-search-autocomplete>)
Statusstable
Also installsprice
Keywordssearch, recherche, autocomplete, combobox, typeahead, suggestions, e-commerce, header

When to use

Avoid when

Install

node scripts/add.mjs search-autocomplete --out ./src/marvelous

AI agent with the Marvelous UI MCP server: install_components({ slugs: ["search-autocomplete"], target_dir: "<absolute path>/src/marvelous", framework: "react" }).

Files copied (dependencies included): tokens/tokens.css, core/base.css, core/dismiss.js, core/dom.js, core/element.js, core/motion.js, components/search-autocomplete/search-autocomplete.js, components/search-autocomplete/search-autocomplete.css, components/price/price.js, components/price/price.css.

Usage

Canonical markup — start from it and customize with attributes, data-* and CSS variables:

<div id="sa-demo" style="width:min(100%,46rem);margin-inline:auto;display:grid;gap:2rem;padding-bottom:26rem">
  <style>
    #sa-demo .bar { display:flex; align-items:center; gap:1.25rem; padding:.875rem 1rem; border:1px solid var(--mv-border); border-radius:var(--mv-radius-xl); background:var(--mv-surface) }
    #sa-demo .bar b { font-weight:600; letter-spacing:.14em; text-transform:uppercase; font-size:.8125rem; white-space:nowrap }
    #sa-demo .bar mv-search-autocomplete { flex:1; min-width:0 }
    #sa-demo .log { margin:0; color:var(--mv-fg-muted); font-size:.8125rem; text-align:center }
    @media (width < 34rem) { #sa-demo .bar b { display:none } }
  </style>
  <div class="bar">
    <b>Lumen Supply</b>
    <mv-search-autocomplete id="sa-search" trending="merino sweater;scented candle;gift box;leather sneakers" shortcut="/">
      <form class="mv-search" role="search" action="#search">
        <label class="mv-sr-only" for="sa-q">Search products</label>
        <div class="mv-search-field"><input class="mv-search-input" id="sa-q" name="q" type="search" placeholder="Search products, materials…"></div>
      </form>
      <script type="application/json" class="mv-search-data">{"terms":["sweater","merino sweater","turtleneck sweater","men's sweater","women's sweater","wool sweater","mug","stoneware mug","candle","scented candle","gift candle","lamp","leather sneakers","tote bag","cardigan","wool cardigan","water bottle","wireless headphones","gift card","gift box"],"products":[{"title":"Merino crewneck sweater","category":"Knitwear","price":89,"compareAt":112,"image":"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 500'%3E%3Cdefs%3E%3ClinearGradient id='bg' x1='0' y1='0' x2='0' y2='1'%3E%3Cstop offset='0' stop-color='oklch(0.95 0.012 250)'/%3E%3Cstop offset='1' stop-color='oklch(0.87 0.025 255)'/%3E%3C/linearGradient%3E%3CradialGradient id='fl'%3E%3Cstop offset='0' stop-color='black' stop-opacity='.22'/%3E%3Cstop offset='1' stop-color='black' stop-opacity='0'/%3E%3C/radialGradient%3E%3ClinearGradient id='sh' x1='0' x2='1'%3E%3Cstop offset='0' stop-color='white' stop-opacity='.22'/%3E%3Cstop offset='.55' stop-color='white' stop-opacity='0'/%3E%3Cstop offset='1' stop-color='black' stop-opacity='.16'/%3E%3C/linearGradient%3E%3C/defs%3E%3Crect width='400' height='500' fill='url(%23bg)'/%3E%3Cdefs%3E%3Cpattern id='k' width='12' height='10' patternUnits='userSpaceOnUse'%3E%3Cpath d='M0 0l6 8 6-8' fill='none' stroke='black' stroke-opacity='.09' stroke-width='1.6'/%3E%3C/pattern%3E%3C/defs%3E%3Cellipse cx='200' cy='420' rx='150' ry='18' fill='url(%23fl)' opacity='1'/%3E%3Cpath d='M160 118 Q200 142 240 118 L276 128 Q300 140 310 176 L336 318 L300 331 L268 222 L267 388 Q200 397 133 388 L132 222 L100 331 L64 318 L90 176 Q100 140 124 128 Z' fill='oklch(0.34 0.05 262)'/%3E%3Cpath d='M160 118 Q200 142 240 118 L276 128 Q300 140 310 176 L336 318 L300 331 L268 222 L267 388 Q200 397 133 388 L132 222 L100 331 L64 318 L90 176 Q100 140 124 128 Z' fill='url(%23k)'/%3E%3Cpath d='M160 118 Q200 142 240 118 L276 128 Q300 140 310 176 L336 318 L300 331 L268 222 L267 388 Q200 397 133 388 L132 222 L100 331 L64 318 L90 176 Q100 140 124 128 Z' fill='url(%23sh)'/%3E%3Cpath d='M160 118 Q200 152 240 118 Q200 136 160 118Z' fill='black' fill-opacity='.22'/%3E%3Cpath d='M154 116 Q200 160 246 116' fill='none' stroke='black' stroke-opacity='.12' stroke-width='5'/%3E%3Cpath d='M133 370 Q200 379 267 370 L267 388 Q200 397 133 388 Z' fill='black' fill-opacity='.1'/%3E%3Cpath d='M64 318 L100 331 L103 316 L68 303 Z' fill='black' fill-opacity='.1'/%3E%3Cpath d='M336 318 L300 331 L297 316 L332 303 Z' fill='black' fill-opacity='.1'/%3E%3Cpath d='M132 222 L133 380 M268 222 L267 380' stroke='black' stroke-opacity='.08' stroke-width='3'/%3E%3C/svg%3E","meta":"Midnight blue · 5 colors","tags":["sweater","wool","merino","men","women"],"href":"#merino-crewneck-sweater"},{"title":"Merino crewneck sweater, Sand","category":"Knitwear","price":89,"image":"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 500'%3E%3Cdefs%3E%3ClinearGradient id='bg' x1='0' y1='0' x2='0' y2='1'%3E%3Cstop offset='0' stop-color='oklch(0.97 0.012 80)'/%3E%3Cstop offset='1' stop-color='oklch(0.91 0.025 75)'/%3E%3C/linearGradient%3E%3CradialGradient id='fl'%3E%3Cstop offset='0' stop-color='black' stop-opacity='.22'/%3E%3Cstop offset='1' stop-color='black' stop-opacity='0'/%3E%3C/radialGradient%3E%3ClinearGradient id='sh' x1='0' x2='1'%3E%3Cstop offset='0' stop-color='white' stop-opacity='.22'/%3E%3Cstop offset='.55' stop-color='white' stop-opacity='0'/%3E%3Cstop offset='1' stop-color='black' stop-opacity='.16'/%3E%3C/linearGradient%3E%3C/defs%3E%3Crect width='400' height='500' fill='url(%23bg)'/%3E%3Cdefs%3E%3Cpattern id='k' width='12' height='10' patternUnits='userSpaceOnUse'%3E%3Cpath d='M0 0l6 8 6-8' fill='none' stroke='black' stroke-opacity='.09' stroke-width='1.6'/%3E%3C/pattern%3E%3C/defs%3E%3Cellipse cx='200' cy='420' rx='150' ry='18' fill='url(%23fl)' opacity='1'/%3E%3Cpath d='M160 118 Q200 142 240 118 L276 128 Q300 140 310 176 L336 318 L300 331 L268 222 L267 388 Q200 397 133 388 L132 222 L100 331 L64 318 L90 176 Q100 140 124 128 Z' fill='oklch(0.8 0.05 75)'/%3E%3Cpath d='M160 118 Q200 142 240 118 L276 128 Q300 140 310 176 L336 318 L300 331 L268 222 L267 388 Q200 397 133 388 L132 222 L100 331 L64 318 L90 176 Q100 140 124 128 Z' fill='url(%23k)'/%3E%3Cpath d='M160 118 Q200 142 240 118 L276 128 Q300 140 310 176 L336 318 L300 331 L268 222 L267 388 Q200 397 133 388 L132 222 L100 331 L64 318 L90 176 Q100 140 124 128 Z' fill='url(%23sh)'/%3E%3Cpath d='M160 118 Q200 152 240 118 Q200 136 160 118Z' fill='black' fill-opacity='.22'/%3E%3Cpath d='M154 116 Q200 160 246 116' fill='none' stroke='black' stroke-opacity='.12' stroke-width='5'/%3E%3Cpath d='M133 370 Q200 379 267 370 L267 388 Q200 397 133 388 Z' fill='black' fill-opacity='.1'/%3E%3Cpath d='M64 318 L100 331 L103 316 L68 303 Z' fill='black' fill-opacity='.1'/%3E%3Cpath d='M336 318 L300 331 L297 316 L332 303 Z' fill='black' fill-opacity='.1'/%3E%3Cpath d='M132 222 L133 380 M268 222 L267 380' stroke='black' stroke-opacity='.08' stroke-width='3'/%3E%3C/svg%3E","meta":"Sand · Extra-fine wool","tags":["sweater","wool","beige"],"href":"#merino-crewneck-sweater-sand"},{"title":"Merino button cardigan","category":"Knitwear","price":119,"image":"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 500'%3E%3Cdefs%3E%3ClinearGradient id='bg' x1='0' y1='0' x2='0' y2='1'%3E%3Cstop offset='0' stop-color='oklch(0.96 0.015 145)'/%3E%3Cstop offset='1' stop-color='oklch(0.89 0.03 150)'/%3E%3C/linearGradient%3E%3CradialGradient id='fl'%3E%3Cstop offset='0' stop-color='black' stop-opacity='.22'/%3E%3Cstop offset='1' stop-color='black' stop-opacity='0'/%3E%3C/radialGradient%3E%3ClinearGradient id='sh' x1='0' x2='1'%3E%3Cstop offset='0' stop-color='white' stop-opacity='.22'/%3E%3Cstop offset='.55' stop-color='white' stop-opacity='0'/%3E%3Cstop offset='1' stop-color='black' stop-opacity='.16'/%3E%3C/linearGradient%3E%3C/defs%3E%3Crect width='400' height='500' fill='url(%23bg)'/%3E%3Cdefs%3E%3Cpattern id='k' width='12' height='10' patternUnits='userSpaceOnUse'%3E%3Cpath d='M0 0l6 8 6-8' fill='none' stroke='black' stroke-opacity='.09' stroke-width='1.6'/%3E%3C/pattern%3E%3C/defs%3E%3Crect x='0' y='0' width='400' height='500' fill='white' fill-opacity='.18'/%3E%3Cpath d='M200 58 q0-16 12-16 q12 0 12 12 q0 10-12 14 L200 78' fill='none' stroke='oklch(0.55 0.02 60)' stroke-width='5' stroke-linecap='round'/%3E%3Cpath d='M200 78 L96 124 L304 124 Z' fill='none' stroke='oklch(0.6 0.08 60)' stroke-width='8' stroke-linejoin='round'/%3E%3Cg transform='translate(40 30) scale(.8)'%3E%3Cpath d='M160 118 Q200 142 240 118 L276 128 Q300 140 310 176 L336 318 L300 331 L268 222 L267 388 Q200 397 133 388 L132 222 L100 331 L64 318 L90 176 Q100 140 124 128 Z' fill='oklch(0.7 0.06 150)'/%3E%3Cpath d='M160 118 Q200 142 240 118 L276 128 Q300 140 310 176 L336 318 L300 331 L268 222 L267 388 Q200 397 133 388 L132 222 L100 331 L64 318 L90 176 Q100 140 124 128 Z' fill='url(%23k)'/%3E%3Cpath d='M160 118 Q200 142 240 118 L276 128 Q300 140 310 176 L336 318 L300 331 L268 222 L267 388 Q200 397 133 388 L132 222 L100 331 L64 318 L90 176 Q100 140 124 128 Z' fill='url(%23sh)'/%3E%3Cpath d='M160 118 Q200 152 240 118 Q200 136 160 118Z' fill='black' fill-opacity='.2'/%3E%3Cpath d='M133 372 Q200 380 267 372 L267 388 Q200 397 133 388 Z' fill='black' fill-opacity='.1'/%3E%3C/g%3E%3Cpath d='M300 470 c-4-60 6-110 30-150 c-2 50-10 100-12 150z' fill='oklch(0.55 0.08 150)' opacity='.55'/%3E%3Cpath d='M318 470 c8-52 30-86 58-104 c-14 38-30 72-40 104z' fill='oklch(0.5 0.08 150)' opacity='.5'/%3E%3Crect x='292' y='452' width='64' height='48' rx='6' fill='oklch(0.72 0.06 55)' opacity='.9'/%3E%3C/svg%3E","meta":"Sage · Regular fit","tags":["cardigan","wool"],"href":"#merino-button-cardigan"},{"title":"Recycled wool cable-knit sweater","category":"Knitwear","price":99,"compareAt":129,"image":"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 500'%3E%3Cdefs%3E%3ClinearGradient id='bg' x1='0' y1='0' x2='0' y2='1'%3E%3Cstop offset='0' stop-color='oklch(0.95 0.01 90)'/%3E%3Cstop offset='1' stop-color='oklch(0.87 0.02 85)'/%3E%3C/linearGradient%3E%3CradialGradient id='fl'%3E%3Cstop offset='0' stop-color='black' stop-opacity='.22'/%3E%3Cstop offset='1' stop-color='black' stop-opacity='0'/%3E%3C/radialGradient%3E%3ClinearGradient id='sh' x1='0' x2='1'%3E%3Cstop offset='0' stop-color='white' stop-opacity='.22'/%3E%3Cstop offset='.55' stop-color='white' stop-opacity='0'/%3E%3Cstop offset='1' stop-color='black' stop-opacity='.16'/%3E%3C/linearGradient%3E%3C/defs%3E%3Crect width='400' height='500' fill='url(%23bg)'/%3E%3Cdefs%3E%3Cpattern id='k' width='12' height='10' patternUnits='userSpaceOnUse'%3E%3Cpath d='M0 0l6 8 6-8' fill='none' stroke='black' stroke-opacity='.09' stroke-width='1.6'/%3E%3C/pattern%3E%3C/defs%3E%3Cellipse cx='200' cy='392' rx='150' ry='16' fill='url(%23fl)' opacity='1'/%3E%3Crect x='96' y='292' width='208' height='96' rx='16' fill='oklch(0.93 0.02 90)' style='filter:brightness(.9)'/%3E%3Crect x='96' y='292' width='208' height='96' rx='16' fill='url(%23k)'/%3E%3Crect x='96' y='292' width='208' height='96' rx='16' fill='url(%23sh)'/%3E%3Cpath d='M104 356h192' stroke='black' stroke-opacity='.12' stroke-width='3'/%3E%3Crect x='110' y='190' width='180' height='112' rx='16' fill='oklch(0.93 0.02 90)'/%3E%3Crect x='110' y='190' width='180' height='112' rx='16' fill='url(%23k)'/%3E%3Crect x='110' y='190' width='180' height='112' rx='16' fill='url(%23sh)'/%3E%3Cpath d='M160 190 Q200 232 240 190' fill='black' fill-opacity='.14'/%3E%3Cpath d='M166 190 Q200 222 234 190' fill='none' stroke='black' stroke-opacity='.18' stroke-width='5'/%3E%3Cpath d='M118 268h164' stroke='black' stroke-opacity='.1' stroke-width='3'/%3E%3C/svg%3E","meta":"Crème · Recycled wool","tags":["sweater","winter"],"href":"#recycled-wool-cable-knit-sweater"},{"title":"Mock-neck sweater, Dusty pink","category":"Knitwear","price":95,"image":"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 500'%3E%3Cdefs%3E%3ClinearGradient id='bg' x1='0' y1='0' x2='0' y2='1'%3E%3Cstop offset='0' stop-color='oklch(0.97 0.012 20)'/%3E%3Cstop offset='1' stop-color='oklch(0.9 0.03 15)'/%3E%3C/linearGradient%3E%3CradialGradient id='fl'%3E%3Cstop offset='0' stop-color='black' stop-opacity='.22'/%3E%3Cstop offset='1' stop-color='black' stop-opacity='0'/%3E%3C/radialGradient%3E%3ClinearGradient id='sh' x1='0' x2='1'%3E%3Cstop offset='0' stop-color='white' stop-opacity='.22'/%3E%3Cstop offset='.55' stop-color='white' stop-opacity='0'/%3E%3Cstop offset='1' stop-color='black' stop-opacity='.16'/%3E%3C/linearGradient%3E%3C/defs%3E%3Crect width='400' height='500' fill='url(%23bg)'/%3E%3Cdefs%3E%3Cpattern id='k' width='12' height='10' patternUnits='userSpaceOnUse'%3E%3Cpath d='M0 0l6 8 6-8' fill='none' stroke='black' stroke-opacity='.09' stroke-width='1.6'/%3E%3C/pattern%3E%3C/defs%3E%3Cellipse cx='200' cy='420' rx='150' ry='18' fill='url(%23fl)' opacity='1'/%3E%3Cpath d='M160 118 Q200 142 240 118 L276 128 Q300 140 310 176 L336 318 L300 331 L268 222 L267 388 Q200 397 133 388 L132 222 L100 331 L64 318 L90 176 Q100 140 124 128 Z' fill='oklch(0.8 0.07 15)'/%3E%3Cpath d='M160 118 Q200 142 240 118 L276 128 Q300 140 310 176 L336 318 L300 331 L268 222 L267 388 Q200 397 133 388 L132 222 L100 331 L64 318 L90 176 Q100 140 124 128 Z' fill='url(%23k)'/%3E%3Cpath d='M160 118 Q200 142 240 118 L276 128 Q300 140 310 176 L336 318 L300 331 L268 222 L267 388 Q200 397 133 388 L132 222 L100 331 L64 318 L90 176 Q100 140 124 128 Z' fill='url(%23sh)'/%3E%3Cpath d='M160 118 Q200 152 240 118 Q200 136 160 118Z' fill='black' fill-opacity='.22'/%3E%3Cpath d='M154 116 Q200 160 246 116' fill='none' stroke='black' stroke-opacity='.12' stroke-width='5'/%3E%3Cpath d='M133 370 Q200 379 267 370 L267 388 Q200 397 133 388 Z' fill='black' fill-opacity='.1'/%3E%3Cpath d='M64 318 L100 331 L103 316 L68 303 Z' fill='black' fill-opacity='.1'/%3E%3Cpath d='M336 318 L300 331 L297 316 L332 303 Z' fill='black' fill-opacity='.1'/%3E%3Cpath d='M132 222 L133 380 M268 222 L267 380' stroke='black' stroke-opacity='.08' stroke-width='3'/%3E%3C/svg%3E","meta":"Dusty pink · New","tags":["sweater","turtleneck"],"href":"#mock-neck-sweater-dusty-pink"},{"title":"Glazed stoneware mug","category":"Tableware","price":24.9,"image":"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 500'%3E%3Cdefs%3E%3ClinearGradient id='bg' x1='0' y1='0' x2='0' y2='1'%3E%3Cstop offset='0' stop-color='oklch(0.96 0.015 145)'/%3E%3Cstop offset='1' stop-color='oklch(0.89 0.03 150)'/%3E%3C/linearGradient%3E%3CradialGradient id='fl'%3E%3Cstop offset='0' stop-color='black' stop-opacity='.22'/%3E%3Cstop offset='1' stop-color='black' stop-opacity='0'/%3E%3C/radialGradient%3E%3ClinearGradient id='sh' x1='0' x2='1'%3E%3Cstop offset='0' stop-color='white' stop-opacity='.22'/%3E%3Cstop offset='.55' stop-color='white' stop-opacity='0'/%3E%3Cstop offset='1' stop-color='black' stop-opacity='.16'/%3E%3C/linearGradient%3E%3C/defs%3E%3Crect width='400' height='500' fill='url(%23bg)'/%3E%3Cellipse cx='200' cy='392' rx='130' ry='16' fill='url(%23fl)' opacity='1'/%3E%3Cpath d='M290 220 q64 0 64 60 q0 60-64 60' fill='none' stroke='oklch(0.7 0.06 150)' stroke-width='22' stroke-linecap='round'/%3E%3Cpath d='M110 170 L290 170 L284 370 Q200 392 116 370 Z' fill='oklch(0.86 0.03 75)'/%3E%3Cpath d='M110 170 L290 170 L287 270 C250 286 236 256 206 280 C176 300 150 266 113 284 Z' fill='oklch(0.7 0.06 150)'/%3E%3Cpath d='M110 170 L290 170 L284 370 Q200 392 116 370 Z' fill='url(%23sh)'/%3E%3Cellipse cx='200' cy='170' rx='90' ry='16' fill='oklch(0.36 0.05 55)'/%3E%3Cellipse cx='200' cy='170' rx='90' ry='16' fill='none' stroke='oklch(0.7 0.06 150)' stroke-width='6' style='filter:brightness(1.1)'/%3E%3C/svg%3E","meta":"Sage · 12 oz","tags":["cup","coffee","tea","stoneware"],"href":"#glazed-stoneware-mug"},{"title":"Stoneware mug, Brick","category":"Tableware","price":24.9,"compareAt":29.9,"image":"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 500'%3E%3Cdefs%3E%3ClinearGradient id='bg' x1='0' y1='0' x2='0' y2='1'%3E%3Cstop offset='0' stop-color='oklch(0.96 0.015 45)'/%3E%3Cstop offset='1' stop-color='oklch(0.89 0.035 40)'/%3E%3C/linearGradient%3E%3CradialGradient id='fl'%3E%3Cstop offset='0' stop-color='black' stop-opacity='.22'/%3E%3Cstop offset='1' stop-color='black' stop-opacity='0'/%3E%3C/radialGradient%3E%3ClinearGradient id='sh' x1='0' x2='1'%3E%3Cstop offset='0' stop-color='white' stop-opacity='.22'/%3E%3Cstop offset='.55' stop-color='white' stop-opacity='0'/%3E%3Cstop offset='1' stop-color='black' stop-opacity='.16'/%3E%3C/linearGradient%3E%3C/defs%3E%3Crect width='400' height='500' fill='url(%23bg)'/%3E%3Cellipse cx='200' cy='392' rx='130' ry='16' fill='url(%23fl)' opacity='1'/%3E%3Cpath d='M290 220 q64 0 64 60 q0 60-64 60' fill='none' stroke='oklch(0.58 0.13 38)' stroke-width='22' stroke-linecap='round'/%3E%3Cpath d='M110 170 L290 170 L284 370 Q200 392 116 370 Z' fill='oklch(0.86 0.03 75)'/%3E%3Cpath d='M110 170 L290 170 L287 270 C250 286 236 256 206 280 C176 300 150 266 113 284 Z' fill='oklch(0.58 0.13 38)'/%3E%3Cpath d='M110 170 L290 170 L284 370 Q200 392 116 370 Z' fill='url(%23sh)'/%3E%3Cellipse cx='200' cy='170' rx='90' ry='16' fill='oklch(0.36 0.05 55)'/%3E%3Cellipse cx='200' cy='170' rx='90' ry='16' fill='none' stroke='oklch(0.58 0.13 38)' stroke-width='6' style='filter:brightness(1.1)'/%3E%3C/svg%3E","meta":"Brick · 12 oz","tags":["cup","stoneware"],"href":"#stoneware-mug-brick"},{"title":"Fig scented candle","category":"Candles","price":36,"image":"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 500'%3E%3Cdefs%3E%3ClinearGradient id='bg' x1='0' y1='0' x2='0' y2='1'%3E%3Cstop offset='0' stop-color='oklch(0.97 0.012 20)'/%3E%3Cstop offset='1' stop-color='oklch(0.9 0.03 15)'/%3E%3C/linearGradient%3E%3CradialGradient id='fl'%3E%3Cstop offset='0' stop-color='black' stop-opacity='.22'/%3E%3Cstop offset='1' stop-color='black' stop-opacity='0'/%3E%3C/radialGradient%3E%3ClinearGradient id='sh' x1='0' x2='1'%3E%3Cstop offset='0' stop-color='white' stop-opacity='.22'/%3E%3Cstop offset='.55' stop-color='white' stop-opacity='0'/%3E%3Cstop offset='1' stop-color='black' stop-opacity='.16'/%3E%3C/linearGradient%3E%3C/defs%3E%3Crect width='400' height='500' fill='url(%23bg)'/%3E%3Cdefs%3E%3ClinearGradient id='gls' x1='0' x2='1'%3E%3Cstop offset='0' stop-color='white' stop-opacity='.55'/%3E%3Cstop offset='.3' stop-color='white' stop-opacity='.1'/%3E%3Cstop offset='1' stop-color='white' stop-opacity='.35'/%3E%3C/linearGradient%3E%3CradialGradient id='fg'%3E%3Cstop offset='0' stop-color='oklch(0.95 0.12 90)' stop-opacity='.8'/%3E%3Cstop offset='1' stop-color='oklch(0.9 0.12 80)' stop-opacity='0'/%3E%3C/radialGradient%3E%3C/defs%3E%3Cellipse cx='200' cy='404' rx='120' ry='14' fill='url(%23fl)' opacity='1'/%3E%3Crect x='120' y='200' width='160' height='200' rx='18' fill='oklch(0.8 0.07 15)'/%3E%3Crect x='120' y='200' width='160' height='200' rx='18' fill='url(%23sh)'/%3E%3Crect x='120' y='200' width='160' height='200' rx='18' fill='url(%23gls)'/%3E%3Cellipse cx='200' cy='214' rx='72' ry='10' fill='oklch(0.95 0.02 85)'/%3E%3Cpath d='M200 214 v-18' stroke='oklch(0.25 0.01 60)' stroke-width='3'/%3E%3Crect x='144' y='270' width='112' height='70' rx='4' fill='oklch(0.97 0.01 90)'/%3E%3Ctext x='200' y='302' text-anchor='middle' font-family='Georgia,serif' font-size='18' fill='oklch(0.3 0.02 60)'%3EFig%3C/text%3E%3Ctext x='200' y='322' text-anchor='middle' font-family='Arial,sans-serif' font-size='9' letter-spacing='2' fill='oklch(0.45 0.02 60)'%3EPLANT WAX %C2%B7 6.3 OZ%3C/text%3E%3C/svg%3E","meta":"6.3 oz · 45 h","tags":["fragrance","soy wax","gift"],"href":"#fig-scented-candle"},{"title":"Woodfire scented candle","category":"Candles","price":36,"image":"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 500'%3E%3Cdefs%3E%3ClinearGradient id='bg' x1='0' y1='0' x2='0' y2='1'%3E%3Cstop offset='0' stop-color='oklch(0.97 0.02 85)'/%3E%3Cstop offset='1' stop-color='oklch(0.9 0.04 80)'/%3E%3C/linearGradient%3E%3CradialGradient id='fl'%3E%3Cstop offset='0' stop-color='black' stop-opacity='.22'/%3E%3Cstop offset='1' stop-color='black' stop-opacity='0'/%3E%3C/radialGradient%3E%3ClinearGradient id='sh' x1='0' x2='1'%3E%3Cstop offset='0' stop-color='white' stop-opacity='.22'/%3E%3Cstop offset='.55' stop-color='white' stop-opacity='0'/%3E%3Cstop offset='1' stop-color='black' stop-opacity='.16'/%3E%3C/linearGradient%3E%3C/defs%3E%3Crect width='400' height='500' fill='url(%23bg)'/%3E%3Cdefs%3E%3ClinearGradient id='gls' x1='0' x2='1'%3E%3Cstop offset='0' stop-color='white' stop-opacity='.55'/%3E%3Cstop offset='.3' stop-color='white' stop-opacity='.1'/%3E%3Cstop offset='1' stop-color='white' stop-opacity='.35'/%3E%3C/linearGradient%3E%3CradialGradient id='fg'%3E%3Cstop offset='0' stop-color='oklch(0.95 0.12 90)' stop-opacity='.8'/%3E%3Cstop offset='1' stop-color='oklch(0.9 0.12 80)' stop-opacity='0'/%3E%3C/radialGradient%3E%3C/defs%3E%3Ccircle cx='200' cy='170' r='120' fill='url(%23fg)'/%3E%3Cellipse cx='200' cy='404' rx='120' ry='14' fill='url(%23fl)' opacity='1'/%3E%3Crect x='120' y='200' width='160' height='200' rx='18' fill='oklch(0.74 0.13 75)'/%3E%3Crect x='120' y='200' width='160' height='200' rx='18' fill='url(%23sh)'/%3E%3Crect x='120' y='200' width='160' height='200' rx='18' fill='url(%23gls)'/%3E%3Cellipse cx='200' cy='214' rx='72' ry='10' fill='oklch(0.95 0.02 85)'/%3E%3Cpath d='M200 214 v-18' stroke='oklch(0.25 0.01 60)' stroke-width='3'/%3E%3Cpath d='M200 150 q14 22 0 42 q-14-20 0-42' fill='oklch(0.85 0.15 75)'/%3E%3Cpath d='M200 166 q6 12 0 24 q-6-12 0-24' fill='white'/%3E%3Crect x='144' y='270' width='112' height='70' rx='4' fill='oklch(0.97 0.01 90)'/%3E%3Ctext x='200' y='302' text-anchor='middle' font-family='Georgia,serif' font-size='18' fill='oklch(0.3 0.02 60)'%3EFig%3C/text%3E%3Ctext x='200' y='322' text-anchor='middle' font-family='Arial,sans-serif' font-size='9' letter-spacing='2' fill='oklch(0.45 0.02 60)'%3EPLANT WAX %C2%B7 6.3 OZ%3C/text%3E%3C/svg%3E","meta":"6.3 oz · 45 h","tags":["fragrance","winter","gift"],"href":"#woodfire-scented-candle"},{"title":"Halo table lamp","category":"Lighting","price":149,"image":"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 500'%3E%3Cdefs%3E%3ClinearGradient id='bg' x1='0' y1='0' x2='0' y2='1'%3E%3Cstop offset='0' stop-color='oklch(0.3 0.02 270)'/%3E%3Cstop offset='1' stop-color='oklch(0.18 0.015 270)'/%3E%3C/linearGradient%3E%3CradialGradient id='fl'%3E%3Cstop offset='0' stop-color='black' stop-opacity='.22'/%3E%3Cstop offset='1' stop-color='black' stop-opacity='0'/%3E%3C/radialGradient%3E%3ClinearGradient id='sh' x1='0' x2='1'%3E%3Cstop offset='0' stop-color='white' stop-opacity='.22'/%3E%3Cstop offset='.55' stop-color='white' stop-opacity='0'/%3E%3Cstop offset='1' stop-color='black' stop-opacity='.16'/%3E%3C/linearGradient%3E%3C/defs%3E%3Crect width='400' height='500' fill='url(%23bg)'/%3E%3Cdefs%3E%3CradialGradient id='gl'%3E%3Cstop offset='0' stop-color='oklch(0.95 0.08 85)' stop-opacity='.9'/%3E%3Cstop offset='.45' stop-color='oklch(0.85 0.1 75)' stop-opacity='.35'/%3E%3Cstop offset='1' stop-color='oklch(0.8 0.1 70)' stop-opacity='0'/%3E%3C/radialGradient%3E%3CradialGradient id='gb' cx='.38' cy='.34'%3E%3Cstop offset='0' stop-color='white'/%3E%3Cstop offset='1' stop-color='oklch(0.97 0.05 90)' stop-opacity='.85'/%3E%3C/radialGradient%3E%3C/defs%3E%3Ccircle cx='200' cy='200' r='220' fill='url(%23gl)'/%3E%3Cellipse cx='200' cy='424' rx='110' ry='12' fill='url(%23fl)' opacity='1'/%3E%3Ccircle cx='200' cy='210' r='118' fill='url(%23gb)'/%3E%3Cpath d='M168 318 L232 318 L246 404 Q200 420 154 404 Z' fill='oklch(0.93 0.02 90)'/%3E%3Cpath d='M168 318 L232 318 L246 404 Q200 420 154 404 Z' fill='url(%23sh)'/%3E%3Crect x='160' y='312' width='80' height='12' rx='6' fill='oklch(0.72 0.1 80)'/%3E%3C/svg%3E","meta":"Blown glass · LED","tags":["light","decor","living room"],"href":"#halo-table-lamp"},{"title":"Pebbled leather sneakers","category":"Shoes","price":129,"image":"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 500'%3E%3Cdefs%3E%3ClinearGradient id='bg' x1='0' y1='0' x2='0' y2='1'%3E%3Cstop offset='0' stop-color='oklch(0.95 0.01 90)'/%3E%3Cstop offset='1' stop-color='oklch(0.87 0.02 85)'/%3E%3C/linearGradient%3E%3CradialGradient id='fl'%3E%3Cstop offset='0' stop-color='black' stop-opacity='.22'/%3E%3Cstop offset='1' stop-color='black' stop-opacity='0'/%3E%3C/radialGradient%3E%3ClinearGradient id='sh' x1='0' x2='1'%3E%3Cstop offset='0' stop-color='white' stop-opacity='.22'/%3E%3Cstop offset='.55' stop-color='white' stop-opacity='0'/%3E%3Cstop offset='1' stop-color='black' stop-opacity='.16'/%3E%3C/linearGradient%3E%3C/defs%3E%3Crect width='400' height='500' fill='url(%23bg)'/%3E%3Cellipse cx='200' cy='322' rx='170' ry='14' fill='url(%23fl)' opacity='1'/%3E%3Cg transform='translate(-10 10)'%3E%3Cpath d='M62 300 L358 300 C362 320 350 336 328 336 L86 336 C68 336 58 320 62 300 Z' fill='oklch(0.97 0.005 90)'/%3E%3Cpath d='M62 318 L360 318' stroke='black' stroke-opacity='.08' stroke-width='3'/%3E%3Cpath d='M68 300 C66 252 106 236 150 232 L206 198 C226 186 252 188 264 204 L292 240 C324 250 348 262 352 286 L354 300 Z' fill='oklch(0.93 0.02 90)'/%3E%3Cpath d='M68 300 C66 252 106 236 150 232 L206 198 C226 186 252 188 264 204 L292 240 C324 250 348 262 352 286 L354 300 Z' fill='url(%23sh)'/%3E%3Cpath d='M292 240 C324 250 348 262 352 286 L354 300 L318 300 C318 278 306 256 292 240Z' fill='black' fill-opacity='.08'/%3E%3Cpath d='M140 292 C184 258 236 250 306 264' fill='none' stroke='white' stroke-opacity='.85' stroke-width='9' stroke-linecap='round'/%3E%3Cpath d='M214 206 l26 36 M226 200 l26 36 M200 214 l28 34' stroke='oklch(0.97 0.005 90)' stroke-width='5' stroke-linecap='round'/%3E%3Cpath d='M206 198 C226 186 252 188 264 204' fill='none' stroke='black' stroke-opacity='.18' stroke-width='5'/%3E%3Ccircle cx='96' cy='262' r='5' fill='white' fill-opacity='.8'/%3E%3C/g%3E%3C/svg%3E","meta":"Off-white · Veg-tanned leather","tags":["sneakers","shoes","leather"],"href":"#pebbled-leather-sneakers"},{"title":"Heavy canvas tote bag","category":"Bags","price":45,"compareAt":59,"image":"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 500'%3E%3Cdefs%3E%3ClinearGradient id='bg' x1='0' y1='0' x2='0' y2='1'%3E%3Cstop offset='0' stop-color='oklch(0.97 0.02 85)'/%3E%3Cstop offset='1' stop-color='oklch(0.9 0.04 80)'/%3E%3C/linearGradient%3E%3CradialGradient id='fl'%3E%3Cstop offset='0' stop-color='black' stop-opacity='.22'/%3E%3Cstop offset='1' stop-color='black' stop-opacity='0'/%3E%3C/radialGradient%3E%3ClinearGradient id='sh' x1='0' x2='1'%3E%3Cstop offset='0' stop-color='white' stop-opacity='.22'/%3E%3Cstop offset='.55' stop-color='white' stop-opacity='0'/%3E%3Cstop offset='1' stop-color='black' stop-opacity='.16'/%3E%3C/linearGradient%3E%3C/defs%3E%3Crect width='400' height='500' fill='url(%23bg)'/%3E%3Cellipse cx='200' cy='418' rx='140' ry='16' fill='url(%23fl)' opacity='1'/%3E%3Cpath d='M150 170 C150 100 250 100 250 170' fill='none' stroke='oklch(0.62 0.06 60)' stroke-width='12' stroke-linecap='round'/%3E%3Cpath d='M168 172 C168 118 232 118 232 172' fill='none' stroke='oklch(0.55 0.06 60)' stroke-width='10' stroke-linecap='round'/%3E%3Cpath d='M102 170 L298 170 L318 410 Q200 420 82 410 Z' fill='oklch(0.74 0.13 75)'/%3E%3Cpath d='M102 170 L298 170 L318 410 Q200 420 82 410 Z' fill='url(%23sh)'/%3E%3Crect x='140' y='150' width='20' height='40' rx='4' fill='oklch(0.55 0.06 60)'/%3E%3Crect x='240' y='150' width='20' height='40' rx='4' fill='oklch(0.55 0.06 60)'/%3E%3Ctext x='200' y='300' text-anchor='middle' font-family='Georgia,serif' font-size='30' letter-spacing='8' fill='black' fill-opacity='.55'%3ELUMEN%3C/text%3E%3Ctext x='200' y='326' text-anchor='middle' font-family='Arial,sans-serif' font-size='10' letter-spacing='4' fill='black' fill-opacity='.45'%3ESTUDIO %C2%B7 LONDON%3C/text%3E%3Cpath d='M102 170 L298 170' stroke='black' stroke-opacity='.15' stroke-width='6'/%3E%3C/svg%3E","meta":"Ochre · Organic cotton","tags":["tote bag","bag","cotton"],"href":"#heavy-canvas-tote-bag"},{"title":"Insulated water bottle, 25 oz","category":"Accessories","price":32,"image":"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 500'%3E%3Cdefs%3E%3ClinearGradient id='bg' x1='0' y1='0' x2='0' y2='1'%3E%3Cstop offset='0' stop-color='oklch(0.96 0.015 230)'/%3E%3Cstop offset='1' stop-color='oklch(0.88 0.035 235)'/%3E%3C/linearGradient%3E%3CradialGradient id='fl'%3E%3Cstop offset='0' stop-color='black' stop-opacity='.22'/%3E%3Cstop offset='1' stop-color='black' stop-opacity='0'/%3E%3C/radialGradient%3E%3ClinearGradient id='sh' x1='0' x2='1'%3E%3Cstop offset='0' stop-color='white' stop-opacity='.22'/%3E%3Cstop offset='.55' stop-color='white' stop-opacity='0'/%3E%3Cstop offset='1' stop-color='black' stop-opacity='.16'/%3E%3C/linearGradient%3E%3C/defs%3E%3Crect width='400' height='500' fill='url(%23bg)'/%3E%3Cellipse cx='200' cy='414' rx='110' ry='14' fill='url(%23fl)' opacity='1'/%3E%3Crect x='156' y='108' width='88' height='300' rx='40' fill='oklch(0.78 0.07 235)'/%3E%3Crect x='156' y='108' width='88' height='300' rx='40' fill='url(%23sh)'/%3E%3Crect x='170' y='70' width='60' height='50' rx='12' fill='oklch(0.3 0.01 270)'/%3E%3Crect x='156' y='170' width='88' height='14' fill='black' fill-opacity='.08'/%3E%3Ctext x='200' y='300' text-anchor='middle' font-family='Arial,sans-serif' font-size='12' letter-spacing='4' fill='white' fill-opacity='.8' transform='rotate(-90 200 300)'%3ELUMEN %C2%B7 25 OZ%3C/text%3E%3C/svg%3E","meta":"Sky · Stainless steel","tags":["bottle","insulated"],"href":"#insulated-water-bottle-25-oz"},{"title":"Studio wireless headphones","category":"Audio","price":189,"compareAt":229,"image":"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 500'%3E%3Cdefs%3E%3ClinearGradient id='bg' x1='0' y1='0' x2='0' y2='1'%3E%3Cstop offset='0' stop-color='oklch(0.95 0.005 270)'/%3E%3Cstop offset='1' stop-color='oklch(0.86 0.01 270)'/%3E%3C/linearGradient%3E%3CradialGradient id='fl'%3E%3Cstop offset='0' stop-color='black' stop-opacity='.22'/%3E%3Cstop offset='1' stop-color='black' stop-opacity='0'/%3E%3C/radialGradient%3E%3ClinearGradient id='sh' x1='0' x2='1'%3E%3Cstop offset='0' stop-color='white' stop-opacity='.22'/%3E%3Cstop offset='.55' stop-color='white' stop-opacity='0'/%3E%3Cstop offset='1' stop-color='black' stop-opacity='.16'/%3E%3C/linearGradient%3E%3C/defs%3E%3Crect width='400' height='500' fill='url(%23bg)'/%3E%3Cellipse cx='200' cy='408' rx='140' ry='14' fill='url(%23fl)' opacity='1'/%3E%3Cg transform='rotate(14 200 280) translate(0 20)'%3E%3Cpath d='M112 270 C112 150 288 150 288 270' fill='none' stroke='oklch(0.25 0.01 270)' stroke-width='22' stroke-linecap='round'/%3E%3Cpath d='M112 270 C112 150 288 150 288 270' fill='none' stroke='white' stroke-opacity='.2' stroke-width='6' stroke-linecap='round' transform='translate(0 -6)'/%3E%3Crect x='80' y='250' width='70' height='112' rx='34' fill='oklch(0.25 0.01 270)'/%3E%3Crect x='250' y='250' width='70' height='112' rx='34' fill='oklch(0.25 0.01 270)'/%3E%3Crect x='80' y='250' width='70' height='112' rx='34' fill='url(%23sh)'/%3E%3Crect x='250' y='250' width='70' height='112' rx='34' fill='url(%23sh)'/%3E%3Crect x='134' y='262' width='22' height='88' rx='11' fill='oklch(0.3 0.01 270)'/%3E%3Crect x='244' y='262' width='22' height='88' rx='11' fill='oklch(0.3 0.01 270)'/%3E%3Ccircle cx='115' cy='306' r='9' fill='white' fill-opacity='.35'/%3E%3C/g%3E%3C/svg%3E","meta":"Black · 40-hour battery","tags":["headphones","bluetooth","audio"],"href":"#studio-wireless-headphones"}]}</script>
    </mv-search-autocomplete>
  </div>
  <p class="log" id="sa-log" aria-live="polite">Try “sweater”, “creme” (no accent) or “gift”. Shortcut: press /.</p>
  <script type="module">
    const s = document.getElementById("sa-search");
    const log = document.getElementById("sa-log");
    try { if (!localStorage.getItem(s.storageKey)) localStorage.setItem(s.storageKey, JSON.stringify(["cardigan", "stoneware mug"])); } catch {}
    s.addEventListener("mv-search", (e) => { e.preventDefault(); log.textContent = `mv-search: “${e.detail.query}”`; });
    s.addEventListener("mv-select", (e) => { if (e.detail.href) { e.preventDefault(); log.textContent = `mv-select: ${e.detail.type} → ${e.detail.value}`; } });
  </script>
</div>

API

Attributes

NameTypeDefaultDescription
trendingstringTrending terms separated by “;”, shown when the field is empty.
shortcutstringGlobal key that focuses the field (e.g. “/”), shown in a <kbd>.
debouncenumber (ms)140Delay before querying.
min-charsnumber1Minimum input length before searching.
max-recent / max-productsnumber5 / 4History entries kept; products shown (local source).
storage-keystringmv-search-recentlocalStorage key for the history (storage errors are ignored).
currency / localestringUSD / en-USPrice formatting.
data-variantfilledBorderless field on a gray background.

Properties

NameTypeDescription
source(query, { signal }) => Promise<{ suggestions, categories, products, total }>Remote data; the signal is aborted when the input changes. products: { title, href, image, price, compareAt, meta }.
catalog{ terms: string[], products: [...] }Catalog for the local source (otherwise read from script.mv-search-data).
value / input / open / recentInput value, input element, panel state, history.

Methods

NameDescription
close()Closes the panel.
addRecent(q) / clearRecent()History.

Events

NameDescription
mv-searchSubmit (Enter, suggestion, “See all results”); cancelable; detail { query }.
mv-selectOption chosen; cancelable (prevents navigation); detail { type: product | category | suggestion | recent | trending | all, value, href, item }.
mv-resultsResults rendered; detail { query, total, suggestions, categories, products }.
mv-clearClear button pressed.

Content structure

NameDescription
form.mv-search > .mv-search-field > input.mv-search-inputNative input (name and form action are preserved).
script.mv-search-dataOptional JSON catalog for the local source.

CSS classes

NameDescription
mv-search / -field / -icon / -input / -clear / -spinner / -kbd / -popup / -history-clear / -listbox / -columns / -col / -group / -group-label / -option / -option-icon / -option-label / -option-count / -mark / -chips / -product-media / -product-body / -product-title / -product-meta / -product-price / -emptyStructure.

Accessibility

ARIA 1.2 combobox pattern: input role=combobox, aria-expanded, aria-controls pointing to a single grouped listbox (labelled role=group), active option via aria-activedescendant (focus stays in the input). Up/Down cycle through all options (wrapping), Enter activates, Escape closes then clears, Tab closes. The number of suggestions and products is announced (role=status), as is “No results”. Strikethrough prices are read as “was”. Highlighting is purely visual (<mark>).