# A product picker for Storyblok, built from one sentence

*Search a shop's catalogue inside the editor and store the product with a small snapshot, so the teaser renders without another request*

By Dominik Angerer · 4 November 2026 · https://d12r.io/e/storyblok-product-picker-field-plugin/

**TL;DR:** A Storyblok field that lets editors search products and stores the id plus a snapshot. Copy the prompt and build it yourself in about three minutes.

Editors shouldn't have to copy product IDs from a shop backend into a text field. This field lets them search the catalogue right in Storyblok and pick a product by its picture, name and price.

> **Try it yourself**
>
> Paste this into Claude Code or Cursor:
>
> ```
> Fetch and follow the Storyblok field plugin instructions at https://raw.githubusercontent.com/DominikAngerer/storyblok-field-wizard/main/generator/PROMPT.md and build this field:
> A product picker for e-commerce teaser blocks, backed by the DummyJSON products API (https://dummyjson.com/products). It stores { "id", "title", "price", "thumbnail" }, where id is the source of truth and the rest is a snapshot taken at pick time; the value is null when empty, and a bare id from an older field is read as { id, title: "", price: 0, thumbnail: "" }. With an empty search box it lists the first products; typing searches by title only, showing thumbnail, title, price and rating (rating is display only, not stored). Because the search endpoint also matches descriptions, fetch all matches and filter by title in the browser before cutting to the limit, and with a category set, load that category and filter in the browser, since the API can't combine category and search. Options: category (default empty = all products; a DummyJSON category slug, malformed values are ignored, a well-formed slug with no products shows a hint to check the option) and limit (default 10, clamped to 1–50). After a pick, show a compact card with Change (reopens the search and turns into Cancel) and Remove.
> ```
>
> Already have the Claude Code plugin? Run:
>
> ```
> /storyblok-field:storyblok-field "A DummyJSON product picker that stores the id plus a title, price and thumbnail snapshot, with optional category and limit options"
> ```
>
> It takes about three minutes and needs Node 22+. You only need a Storyblok personal access token if you want to deploy.

> **Good to know: plugin names are global**
>
> Field plugin names in Storyblok are shared across all spaces, not per space. If the field doesn't render correctly in the preview, or the deploy fails with `DUPLICATED_NAME`, someone else probably has that name already. Give yours a different one, for example `@yourhandle/product-picker`. It happened to me with the [code editor field](https://d12r.io/e/storyblok-code-editor-field-plugin/).

## What it's for

Think of a teaser block on a landing page: "Our pick of the week" with a product image, a name and a price. Without a custom field, a marketer looks up the product in the shop, copies an ID and hopes it's the right one. With this field they type "phone", see the matching products with thumbnails, prices and ratings, and click one. The frontend gets everything it needs to render the teaser. I used [DummyJSON](https://dummyjson.com), a free API with fake products, but the pattern is the same for any shop API.

> **Thanks to DummyJSON**
>
> The products in this field come from [DummyJSON](https://dummyjson.com/), a free fake REST API with placeholder data for development, testing and prototyping, built by [Ovi](https://github.com/ovi). No sign-up and no API key, which made it easy to try field plugins against real-looking data.

## What you get

![Searching "phone" lists every product with "phone" in its title, with thumbnail, price and rating](https://a.storyblok.com/f/296339501219281/2144x2544/6a9d439ec1/dummyjson-product-picker-02-search-phone-43b72e35.png)

*Search narrows the list by title. All eight title matches show up, including iPhone X.*

![After a pick the field shows a compact card with Change and Remove](https://a.storyblok.com/f/296339501219281/2144x1694/b684830cbd/dummyjson-product-picker-03-picked-4c1f31a8.png)

*After a pick: a compact card, and the stored JSON below it in Storyblok's field plugin sandbox.*

![With category set to smartphones and limit 5, a chip shows the category and five phones are listed](https://a.storyblok.com/f/296339501219281/2144x2156/a586c8db09/dummyjson-product-picker-09-category-initial-6480a5dc.png)

*Restricted to one category, with a smaller limit.*

The stored value:

```json
{
  "id": 121,
  "title": "iPhone 5s",
  "price": 199.99,
  "thumbnail": "https://cdn.dummyjson.com/product-images/smartphones/iphone-5s/thumbnail.webp"
}
```

| Option | Default | What it does |
| --- | --- | --- |
| `category` | empty (all products) | A DummyJSON category slug like `smartphones` or `beauty`. Malformed values are ignored. A well-formed slug with no products shows a hint to check the option. |
| `limit` | `10` | Max results shown, 1–50. |

## Using it in the frontend

```jsx
const p = blok.product
{p && (
  <a href={`/products/${p.id}`} className="teaser">
    {p.thumbnail && <img src={p.thumbnail} alt={p.title} />}
    <h3>{p.title}</h3>
    <span>${p.price.toFixed(2)}</span>
  </a>
)}
```

The snapshot doesn't update itself. For live stock or the current price, fetch the product by `id`.

## What I learned building it

- **The id plus a snapshot is the right default.** The id stays the source of truth, and the title, price and thumbnail let the frontend render without a second request. That became a rule in the guide for every field that picks from an external API.
- **Unit tests were green, and the search was still wrong.** A browser walkthrough in Storyblok's field plugin sandbox found it. The field asked the API for 10 results, but the API matches titles *and* descriptions, and the field then kept only the title matches. Searching "phone" showed 7 products, and "iPhone X" never appeared. The fix loads all matches with a slim `select` and filters by title before cutting to the limit.
- **The docs promised something the code didn't do.** PLUGIN.md said invalid category slugs were ignored. Only malformed ones were. A typo like `smartphone` showed an empty list with no explanation. Now the docs say what happens, and the field shows a hint.
- **DummyJSON's category endpoint ignores the search term**, so with a category set, the field loads the whole category and searches in the browser. The categories are small, so that's fine here.

This field was generated by a fresh agent from one sentence and the guide, in about 2.2 minutes. The full story is in [the article about the original experiment](https://d12r.io/e/midnight-idea-generating-storyblok-field-plugins/). The other fields: [brand color picker](https://d12r.io/e/storyblok-brand-color-picker-field-plugin/), [author picker](https://d12r.io/e/storyblok-author-picker-field-plugin/), [recipe picker](https://d12r.io/e/storyblok-recipe-picker-fullscreen-field-plugin/), [code editor](https://d12r.io/e/storyblok-code-editor-field-plugin/).
