Skip to main content
RapidDev - Software Development Agency
V0 TemplatesUI ComponentBeginner to customize

Cuisine Selector Chips V0 Template: Filter UI Prompts + Supabase

The Cuisine Selector Chips template is a multi-select filter row built with Next.js, shadcn/ui, and Framer Motion. The ChipGroup manages selected cuisines in a Set, each CuisineChip animates on toggle, and a ClearAllButton resets selection. Perfect for food delivery apps or any multi-filter UI. The prompt pack covers single-select mode, URL param persistence, filtering a restaurant list, and wiring chip counts to a live Supabase aggregation query.

UI ComponentBeginner~5 minutes

Best for

Food delivery apps, restaurant finders, or any multi-filter UI needing a toggleable category chip row

Stack

Next.jsTypeScriptTailwind CSSshadcn/uiFramer Motion

A ready-made Cuisine Selector Chips UI you can fork, run, and customize with the prompt pack below.

What's actually inside

The honest engineer's breakdown — what the Cuisine Selector Chipstemplate does, how it's wired, and where it's opinionated.

The Cuisine Selector Chips template is a flex-wrap row of pill-shaped toggle chips that lets users select one or multiple cuisine categories. The ChipGroup component owns a useState Set of selected cuisine keys and passes selection state down to each CuisineChip. When a chip is toggled, Framer Motion fires a spring animation — a subtle scale and background-color transition — that makes the interaction feel snappy without being flashy.

The SelectedSummary component below the row shows '3 cuisines selected' as a live count, which is a small UX detail that helps users understand the current filter state at a glance. A ClearAllButton styled as a ghost button resets the Set to empty. Each CuisineChip uses shadcn/ui's Badge or Toggle as the base primitive, giving you aria-pressed support for screen readers out of the box.

One caveat worth knowing upfront: the template ships with hardcoded chip data — it is not pre-wired to any restaurant database. The cuisine labels and optional count badges are static values from a hardcoded array. If you need real restaurant counts per cuisine from a backend, use the Supabase aggregation prompt from the pack below. Also, if you place the ChipGroup inside a larger form component that re-renders on field changes, you will likely hit the state-reset gotcha — read the Gotchas section before wiring it into a complex form.

Key UI components

ChipGroup

Flex-wrap container managing the array of selected chips via a useState Set

CuisineChip

Individual pill/badge toggle with icon (emoji or lucide-react), label, and selected/unselected visual states

ClearAllButton

Resets the selection Set back to empty, styled as a ghost button

SelectedSummary

Optional text below the chip row showing a live count of selected cuisines (e.g., '3 cuisines selected')

Libraries it leans on

Framer Motion

Subtle scale and background-color spring animation on chip selection toggle

shadcn/ui (Badge, Toggle)

Base primitives for accessible chip toggle behaviour with aria-pressed support

Tailwind CSS

Pill shape (rounded-full), selected ring (ring-2 ring-offset-1), and hover/focus state styling

Fork it and get it running

Forking is a fully in-browser process — click Fork, test the chips, and publish a live URL in under five minutes.

1

Fork the template

Navigate to https://v0.dev/chat/community/FzjrLMu1GZ1 and click 'Fork' to copy the template into your V0 account. A new chat session opens with the ChipGroup source files. You now own this copy and can edit it freely.

Tip: Log in to v0.dev before clicking Fork — you will be redirected to the sign-in page if you are not authenticated.

You should see: The forked project opens with the Vercel Sandbox preview showing a row of cuisine chips with a ClearAllButton.

2

Test chip selection and clear in the preview

In the Vercel Sandbox preview, click several cuisine chips to confirm they toggle on and off with the Framer Motion animation. Check that the SelectedSummary count updates as you select chips. Click the ClearAllButton and verify all chips return to the unselected state.

You should see: Chips toggle with animation, SelectedSummary shows the correct count, and ClearAllButton resets all chips to unselected.

3

Edit chip labels and colours with Design Mode

Press Option+D to open Design Mode. Click on any CuisineChip label to rename it to your own category (e.g., change 'Italian' to 'Vegan' for a health-food app). Change chip colours by editing the Tailwind ring and background classes. Design Mode edits are free and do not spend credits.

Tip: Emoji icons on chips can also be swapped in Design Mode — just click the emoji and type a replacement.

You should see: Updated chip labels and colours appear in the live preview without spending AI credits.

4

Customise chip data and behaviour via AI chat

Use the AI chat to paste prompts from the pack below. The most useful first prompt is 'Add a cuisine count badge' to show restaurant counts next to each chip name. For single-select mode (e.g., a radio-style filter), use the 'Change to single-select mode' prompt. Each AI edit creates a new version in the history panel.

Tip: If you want to change all chip data at once, describe the full list of cuisines in a single prompt rather than one by one.

You should see: Each AI edit updates the Sandbox preview and creates a new version in the history panel for rollback.

5

Publish to a live URL

Click Share (top-right icon) → Publish tab → 'Publish to Production'. Vercel deploys in about 30 seconds and gives you a live *.vercel.app URL. The chip animations and toggle logic work identically in production. Remember to click Publish again after subsequent edits.

You should see: A publicly accessible URL shows the working chip selector with animations to anyone without a V0 login.

6

Export to GitHub (optional)

Open the Git panel → Connect → choose your GitHub repository. V0 creates a branch named v0/main-{hash} and opens a pull request with all source files including the ChipGroup and CuisineChip components. Merge the PR to integrate into your existing Next.js project.

Tip: If you plan to use the chip filter inside a larger page, review the parent-state gotcha in the Gotchas section before integrating.

You should see: A GitHub PR appears with the complete cuisine chip component tree ready to merge.

The prompt pack

Copy-paste these straight into v0's chat to customize the Cuisine Selector Chipstemplate. Each one names this template's own components — no generic filler.

1

Switch ChipGroup to single-select mode

Converts the multi-select chip row into a single-select filter — useful for mutually exclusive categories like meal type (Breakfast, Lunch, Dinner).

Quick win
Paste into v0 chat
Update the ChipGroup so only one CuisineChip can be selected at a time. Replace the useState Set with a single string state holding the selected chip key. Clicking a new chip deselects the previous one and selects the new one. Clicking the already-active chip deselects it (toggle off). The ClearAllButton should reset the string state to null.
2

Add a restaurant count badge to each chip

Shows users how many results each cuisine filter will return before they select it, reducing empty-filter frustration.

Quick win
Paste into v0 chat
Add a small numeric badge to each CuisineChip showing the number of available restaurants for that cuisine. Source the counts from a static `CUISINE_COUNTS` mapping object (e.g., { italian: 42, japanese: 18 }) passed as a prop to the ChipGroup. Display the count in a small rounded badge to the right of the chip label, with a muted colour in the unselected state and a white badge in the selected state.
3

Add horizontal scroll with snap on mobile

Prevents the chip row from wrapping to two lines on mobile, replacing the wrap with a smooth horizontal scroll that snaps between chips.

Medium
Paste into v0 chat
Wrap the ChipGroup in a horizontally scrollable container with scroll-snap-type x mandatory and scroll-behavior smooth. On screens smaller than the md breakpoint, switch the ChipGroup from flex-wrap to flex-nowrap with overflow-x-auto so chips scroll in a single row instead of wrapping. Hide the scrollbar using a CSS override (scrollbar-width: none; -webkit-overflow-scrolling: touch) without adding extra packages.
4

Filter a restaurant list based on selected chips

Connects the chip filter to a restaurant list so selecting chips immediately narrows the visible results — the core UX of a food delivery filter.

Medium
Paste into v0 chat
Add a RestaurantList component below the ChipGroup that renders a grid of restaurant cards. The list should filter a `restaurants` prop array (each item has `id`, `name`, and `cuisine` fields) to only show restaurants whose `cuisine` value is in the ChipGroup's selected Set. When no chips are selected, show all restaurants. When the filtered result is empty, show a 'No restaurants match your filter' empty state with the ClearAllButton visible.
5

Persist selected cuisines to URL query parameters

Makes the chip filter state part of the URL so users can bookmark, share, or back-button to specific filter combinations.

Medium
Paste into v0 chat
Replace the ChipGroup's internal useState Set with Next.js useSearchParams and useRouter so selected chip values are stored in the URL as a query parameter (e.g., ?cuisines=italian,japanese). Selecting or deselecting a chip updates the URL. On page load, initialize the chip selection from the URL params so the filter state is preserved on browser refresh and shareable via link. Wrap the ChipGroup in a Suspense boundary to handle the useSearchParams async read.
6

Pull chip counts from a Supabase aggregation query

Replaces hardcoded counts with live aggregation data from Supabase, so chip badges always reflect the real restaurant database.

Advanced
Paste into v0 chat
Add a Next.js server component that queries Supabase with `SELECT cuisine, COUNT(*) as count FROM restaurants GROUP BY cuisine` using the server-side Supabase client. Pass the result as a `cuisineCounts` prop to the ChipGroup, replacing the hardcoded CUISINE_COUNTS object. Each CuisineChip should display the real count from Supabase. Add SUPABASE_URL and SUPABASE_ANON_KEY to the Vars panel in V0 to enable the connection.

Gotchas when you extend it

The failures people actually hit when they push this template past its defaults — and the exact fix for each.

Selected chip state resets on parent component re-render

Why: If the ChipGroup is inside a form component that re-renders on any field change, a new Set state instance is created each render, wiping the user's chip selection even though they have not touched the chips.

Fix: Lift the chip selection state out of ChipGroup to the parent form level and pass it down as controlled props (`selected` Set + `onSelectionChange` callback), so the parent owns the state and ChipGroup re-renders do not reset it.

Fix prompt — paste into v0
Lift the chip selection state out of ChipGroup and accept it as a `selected` prop (Set) with an `onSelectionChange` callback, so the parent form owns the state and re-renders do not reset the chip selection.
Chips wrap to two rows on mobile instead of scrolling horizontally

Why: The default flex-wrap behaviour creates a second row when chips do not fit in one line, which breaks layouts that expect a single-line filter row above a results list.

Fix: Use a Tailwind responsive prefix to switch from flex-wrap to overflow-x-auto flex-nowrap on screens below the md breakpoint, keeping desktop behaviour (wrapped rows) and enabling mobile horizontal scroll.

Fix prompt — paste into v0
On screens smaller than the md breakpoint, switch the ChipGroup from flex-wrap to overflow-x-auto flex-nowrap so chips scroll horizontally in a single row on mobile instead of wrapping to two lines.
URL param approach causes React hydration mismatch warning

Why: useSearchParams returns null during SSR. If chip selection is initialised directly from URL params at render time, the server render and client hydration produce different initial states, triggering a React warning.

Fix: Wrap the useSearchParams initialization inside a useEffect (so it only runs on the client), or wrap the ChipGroup in a Suspense boundary which defers the client-only read until after hydration.

Fix prompt — paste into v0
Wrap the ChipGroup's useSearchParams initialization inside a useEffect so the initial selected state is always the client-side URL value, preventing React hydration mismatch warnings.
The component at https://ui.shadcn.com/r/styles/new-york-v4/toggle.json was not found.

Why: The Toggle registry component used for chip accessibility may not exist under this path in the current version of the shadcn/ui registry, causing the shadcn auto-install to fail.

Fix: Use a shadcn Badge with a button wrapper instead of Toggle, or inline the toggle logic with a plain HTML button and aria-pressed attribute, styled identically with Tailwind.

Fix prompt — paste into v0
Replace the shadcn Toggle import in CuisineChip with a standard HTML button element that sets aria-pressed based on whether the chip key is in the selected Set, styled identically using Tailwind rounded-full and ring-2 classes.

Template vs. custom — the honest call

A forked template gets you far, fast. Here's where it holds up, and where you'll outgrow it.

The template is enough when

  • You need a multi-select filter row for categories (cuisines, tags, genres) with a clean animated toggle
  • The chip data is static or semi-static (5-20 options) and does not require server-side pagination
  • You are adding it to a food ordering, event listing, or product filtering page as a standalone filter control
  • You want URL-shareable filter state without building a full search engine integration

Go custom when

  • You need server-driven chip options loaded from a dynamic taxonomy with hundreds of entries and typeahead search
  • You need the chip filter to integrate with a full-text search index like Algolia or Typesense with server-side filtering and real-time facet counts
  • Chips need to represent hierarchical categories (cuisine → sub-cuisine) with expandable groups
  • You need per-user saved filter presets stored in a backend and restored across sessions

RapidDev can extend this chip selector into a full-stack filter system with Supabase-backed faceted search and real-time count updates — reach out if your filter logic has outgrown the template.

Frequently asked questions

Is the Cuisine Selector Chips V0 template free?

Yes. It is a free community template on v0.dev. Forking uses credits from your V0 plan, but there is no additional licensing fee. The generated code is yours to keep and use freely.

Can I use this template commercially?

Yes. There are no licensing restrictions on the generated code from v0.dev. Framer Motion and shadcn/ui are both MIT-licensed. You can use this in a commercial product or client project without attribution.

Does the template come pre-wired to a restaurant database?

No. The template ships with hardcoded chip labels and static count data — it is a pure UI component by default. Use the 'Pull chip counts from a Supabase aggregation query' advanced prompt to connect it to real backend data.

Why does my fork break in the V0 preview after I add URL param state?

The most common cause is a React hydration mismatch from reading useSearchParams during SSR. Wrap the ChipGroup in a Suspense boundary or initialize the selection state from params inside a useEffect to ensure it only runs on the client. See the Gotchas section for the fix prompt.

How do I connect the chip counts to a real database?

Use the 'Pull chip counts from a Supabase aggregation query' advanced prompt from the pack. It adds a server component that runs a GROUP BY count query in Supabase and passes the results as a prop to ChipGroup, replacing the static counts. Add SUPABASE_URL and SUPABASE_ANON_KEY in the V0 Vars panel.

Why do my selected chips reset when I type in another form field on the same page?

This is the parent re-render gotcha. If the ChipGroup manages its own state internally, any parent re-render (triggered by form field changes) creates a new state instance and wipes the selection. Lift the selection state to the parent form and pass it down as controlled props using the fix prompt in the Gotchas section.

Can RapidDev extend this chip selector into a full filter system?

Yes. RapidDev can build a full-stack filter system on top of this template with Supabase-backed faceted search, real-time count updates, Algolia integration for large catalogs, and per-user saved filter presets — reach out if the template's scope isn't enough.

Outgrowing the template?

RapidDev turns v0 prototypes into production apps — real auth, database, and payments — at $13K–$25K.

Book a free consultation

30-min call. No commitment.

Want this built for you?

We ship production apps at a fixed price — $13K–$25K, 6–10 weeks, source code yours. You've seen what it takes; we do it every week.

Get a fixed-price quote

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.