Shopify App Store · Public app

SwiftSearch

A published Shopify app that replaces a store’s default search with an instant, typo-tolerant one — and then measures what that search is actually worth in revenue. Built solo, end to end: the search backend, the storefront widget, the merchant admin, billing, and the attribution model behind the numbers.

View on the Shopify App Store

The storefront

Search is the highest-intent surface in a store. Most themes waste it.

A shopper who searches has already decided what they want. The default experience makes them wait for a page reload, then punishes one mistyped character with an empty page. SwiftSearch answers as they type, absorbs the typo, and keeps the shopper inside the panel until they have added to cart.

SwiftSearch storefront search panel resolving the misspelled query "chel" into chef knife products, suggestions, collections, and brands
Timeline2026
RoleProduct, design, engineering, App Store submission
StackTypeScript • React Router • Typesense • Shopify
4.5 KBgzipped core script every storefront page pays for
18 KBUI bundle, fetched only on the first sign of search intent
5×weight an add-to-cart carries over a click when ranking results
7 dayslast-touch window for crediting a sale back to a search

Every decision in this app is a conversion decision wearing engineering clothes.

Typo tolerance is not a search feature, it is the difference between a result page and a bounce. Lazy-loading the UI bundle is not a build detail, it is refusing to tax the 90% of visitors who never search in order to serve the 10% who do. Attribution is not reporting, it is the only thing that tells a merchant whether any of the above mattered.

So the app is built around one loop: make the high-intent moment work, watch where it fails, give the merchant a one-click way to fix it, then prove the fix in revenue.

0theme code edits — installs as an app embed and uninstalls clean
0protected customer data scopes requested
2languages shipped in the widget, English and Greek
Empty state

The moment before the first keystroke is not dead space.

Focusing the search box opens a merchandising surface: the shopper’s own recently viewed products, trending products, popular searches, and popular collections with live counts. Recently viewed is kept client-side and capped, so it works without asking the shopper for anything. A visitor who opens search without knowing the right word gets somewhere to go instead of a blank panel.

SwiftSearch panel on focus showing recently viewed products, trending products, popular searches, and popular collections
Path to cart

When the shopper already knows what they want, the result card is the product page.

Each result carries its variant picker and an Add to cart button, and the theme’s own cart drawer handles the rest — nothing about the store’s cart or checkout changes. On mobile the panel takes the full screen and the button confirms in place, turning into Added with a View cart link rather than throwing the shopper into a page transition mid-decision.

SwiftSearch mobile full-screen search panel with a product added to cart showing an Added confirmation and View cart link
The merchandising loop

A zero-result search is a shopper telling you what you failed to sell them.

The admin lists every query that returned nothing, ranked by how often it happened, with Create synonym sitting on each row. That turns the bleakest number in search analytics into a one-click fix: map the term to products the store already carries, or take it as a stocking decision. The same view shows top queries with click-through and add-to-cart rates, so a popular query with weak CTR surfaces as a relevance problem rather than hiding inside an average.

SwiftSearch admin zero-result searches table listing failed queries with a Create synonym action on each row

Why the decay matters

  • Clicks and add-to-carts from the last 30 days score every product.
  • An add-to-cart is worth five clicks, because intent is not the same as curiosity.
  • A score halves every seven days, so last week’s winner cannot coast on stale traffic.
  • Scores are written back as partial document updates, so ranking moves between full catalogue syncs instead of waiting for one.

Relevance that learns from shopper behaviour, not from my opinion of the catalogue.

Text matching alone ranks a discontinued product the same as the one everybody buys. SwiftSearch folds a popularity score into the relevance sort, built from what shoppers actually did in the panel: clicked, or added to cart.

The half-life is the part that matters. Without decay, a product that had one good week in January outranks the store’s current bestseller forever, and the merchant slowly stops trusting the results. A ranking signal that cannot forget is a ranking signal that goes stale in public.

Measurement

I would rather under-report than take credit I cannot prove.

Line item, not order.

An order that mixes a searched-for product with a browsed one credits only the searched-for line. Whole-order attribution would have been easier and would have flattered the number.

Last touch, seven days.

Long enough to cover the normal consider-then-buy gap, short enough that a search from last month cannot claim today’s order.

No customer data.

A web pixel on checkout_completed sends order id, currency, totals, and line items. The app never requests the read_orders scope and stores no personally identifiable data.

Consent gated, so it under-reports.

Shoppers who decline analytics consent or block storage are invisible to the pixel. A sale is only ever counted when a real engagement preceded it, which makes the figure a floor rather than an estimate.

Share of tracked sales, never of the shop.

The dashboard says share of orders this pixel saw. It never implies a share of the store’s true totals — those live in Shopify Analytics, and pretending otherwise is how attribution dashboards start lying.

One currency, no invented FX.

Money is held in integer minor units of the order’s presentment currency, so a multi-currency shop aggregates per currency instead of being silently converted at a rate nobody chose.

Speed is a conversion feature, so the widget is priced like one.

The storefront pays 4.5 KB gzipped up front. That core script binds to whatever search input the theme already has, watches for the first focus or hover on it, and does nothing else. Only then does it fetch the 18 KB UI bundle — early enough that it is ready before the shopper finishes a keystroke, and never at all for the visitors who never search.

It installs as a theme app embed, so there is no theme code to edit and nothing left behind on uninstall. It does not take over the cart, and it does not change how the store’s products are indexed by search engines. An app that costs a merchant Largest Contentful Paint in exchange for better search has not made them any money.

What shipping it publicly demanded

  • Shopify App Store review: listing, screenshots, screencast, and testing instructions.
  • Billing through the Shopify Billing API across four catalogue-size plans.
  • GDPR compliance webhooks and a hosted privacy policy.
  • Webhook-driven catalogue sync so the index tracks products, collections, and bulk operations.
  • A widget that inherits the host theme’s type, colour, and card shape instead of fighting it.
Under the hood

The stack, named honestly.

  • React Router 7
  • TypeScript
  • Typesense
  • Prisma
  • PostgreSQL
  • Shopify App Bridge
  • Polaris web components
  • Theme app embed
  • App proxy
  • Web Pixels API
  • Shopify Billing API
  • Docker

What this case study should prove.

I can take a conversion problem the whole way down: identify the highest-intent surface in a store, rebuild it, instrument it so the merchant can see where it leaks, and then hold myself to an attribution model strict enough to tell me when I was wrong.

SwiftSearch is not a demo. It is a public Shopify app with billing, compliance webhooks, and merchants who can uninstall it the moment it stops earning its place on the page.

View on the Shopify App Store

If you remember one thing

  • Instant, typo-tolerant search with add-to-cart inside the results.
  • Zero-result queries turned into a one-click synonym fix.
  • Ranking that learns from clicks and add-to-carts, and forgets on a seven-day half-life.
  • Line-item, consent-gated revenue attribution that deliberately under-reports.

Find the gaps in your store's search.

Bring two or three searches that fail to return the products you expect, along with your current theme and search app. We can assess whether configuration, an existing app or a scoped custom change fits the problem.

Discuss a Shopify search project

Practical guides