<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Dang Tran</title>
    <description>The latest articles on DEV Community by Dang Tran (@dang_tran_63f9ff8ece59c73).</description>
    <link>https://dev.to/dang_tran_63f9ff8ece59c73</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3673024%2F4eda0aff-2974-4b22-881b-72141716c683.jpg</url>
      <title>DEV Community: Dang Tran</title>
      <link>https://dev.to/dang_tran_63f9ff8ece59c73</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dang_tran_63f9ff8ece59c73"/>
    <language>en</language>
    <item>
      <title>The Starwarden — browser platformer: collect starlights, fight murklings, beat the darkness</title>
      <dc:creator>Dang Tran</dc:creator>
      <pubDate>Wed, 17 Jun 2026 05:22:01 +0000</pubDate>
      <link>https://dev.to/dang_tran_63f9ff8ece59c73/the-starwarden-browser-platformer-collect-starlights-fight-murklings-beat-the-darkness-2epj</link>
      <guid>https://dev.to/dang_tran_63f9ff8ece59c73/the-starwarden-browser-platformer-collect-starlights-fight-murklings-beat-the-darkness-2epj</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/june-game-jam-2026-06-03"&gt;June Solstice Game Jam&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The Starwarden&lt;/strong&gt; is a browser-based 2D side-scrolling platformer. You are the last Starwarden — a wizard carrying embers of the old light — in a world where a creeping shadow called the &lt;strong&gt;Murk&lt;/strong&gt; has swallowed half the sky.&lt;br&gt;
Each run takes you through &lt;strong&gt;four seasons&lt;/strong&gt; (Spring → Summer → Fall → Winter):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The sky starts every season at &lt;strong&gt;50% darkness&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Darkness &lt;strong&gt;rises passively&lt;/strong&gt; over time (~90 seconds to total night if you do nothing)&lt;/li&gt;
&lt;li&gt;Collect &lt;strong&gt;starlights&lt;/strong&gt; to push the meter back down&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Murklings&lt;/strong&gt; patrol the platforms; touch one and the sky gets darker&lt;/li&gt;
&lt;li&gt;From &lt;strong&gt;Summer&lt;/strong&gt; onward, purple &lt;strong&gt;Striker&lt;/strong&gt; murklings shoot shadow bolts at range&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fireballs&lt;/strong&gt; (Space) destroy enemies but briefly lock your movement during the attack animation&lt;/li&gt;
&lt;li&gt;Clear all four seasons to win; hit &lt;strong&gt;100% darkness&lt;/strong&gt; and you lose
The world is &lt;strong&gt;procedurally generated&lt;/strong&gt; each season — floating platform staircases, parallax backgrounds that change with the season, and starlight spawns guaranteed to be reachable (a BFS reachability pass prunes impossible placements).&lt;/li&gt;
&lt;li&gt;Please turn on the sound when you're playing :-)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Screenshots
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fw11433rjp9vpi8qv733c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fw11433rjp9vpi8qv733c.png" alt="The game tale" width="800" height="591"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk6sttyyp995m3xv832wu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk6sttyyp995m3xv832wu.png" alt=" " width="800" height="591"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fuiv66tf4i3jxcgaye0dy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fuiv66tf4i3jxcgaye0dy.png" alt="Victory screen" width="800" height="591"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Site
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://wizard-game-pi.vercel.app/" rel="noopener noreferrer"&gt;https://wizard-game-pi.vercel.app/&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/sea2709" rel="noopener noreferrer"&gt;
        sea2709
      &lt;/a&gt; / &lt;a href="https://github.com/sea2709/wizard-game" rel="noopener noreferrer"&gt;
        wizard-game
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;The Starwarden&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;A 2D side-scrolling platformer built with &lt;strong&gt;Phaser 4&lt;/strong&gt;, &lt;strong&gt;React 19&lt;/strong&gt;, &lt;strong&gt;TypeScript&lt;/strong&gt;, and &lt;strong&gt;Vite&lt;/strong&gt;. Play as a wizard crossing a procedurally generated world through four seasons — collect starlights to push back the darkness, dodge or defeat murklings, and clear Spring through Winter to win.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;AI / contributor reference:&lt;/strong&gt; See &lt;a href="https://github.com/sea2709/wizard-game/AGENTS.md" rel="noopener noreferrer"&gt;AGENTS.md&lt;/a&gt; for architecture, game logic, world generation, assets, and conventions. Start there instead of reading the full codebase.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Quick start&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;npm install
npm run dev&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Open &lt;a href="http://localhost:8080" rel="nofollow noopener noreferrer"&gt;http://localhost:8080&lt;/a&gt;. The game loads &lt;strong&gt;Story&lt;/strong&gt; → &lt;strong&gt;Instructions&lt;/strong&gt; → &lt;strong&gt;Game&lt;/strong&gt; (MainMenu is registered but skipped on cold start).&lt;/p&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;npm install&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Install dependencies&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;npm run dev&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Development server with hot reload&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;npm run build&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Production build in &lt;code&gt;dist/&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;How to play&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;Each season starts with the sky at &lt;strong&gt;50% darkness&lt;/strong&gt;. Darkness rises passively over time (~90 seconds to reach 100% if you collect nothing). Collect &lt;strong&gt;starlights&lt;/strong&gt; to…&lt;/p&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/sea2709/wizard-game" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Stack
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Choice&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Game engine&lt;/td&gt;
&lt;td&gt;&lt;a href="https://phaser.io/" rel="noopener noreferrer"&gt;Phaser 4&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;UI shell&lt;/td&gt;
&lt;td&gt;&lt;a href="https://react.dev/" rel="noopener noreferrer"&gt;React 19&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Language&lt;/td&gt;
&lt;td&gt;TypeScript&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bundler&lt;/td&gt;
&lt;td&gt;Vite 6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Viewport&lt;/td&gt;
&lt;td&gt;1280 × 960&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;World&lt;/td&gt;
&lt;td&gt;6480 px wide procedural tile grid&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Phaser handles gameplay, physics, and rendering; React mounts the canvas via a thin &lt;code&gt;PhaserGame&lt;/code&gt; wrapper. Scenes emit &lt;code&gt;current-scene-ready&lt;/code&gt; on an &lt;code&gt;EventBus&lt;/code&gt; so React can track the active scene.&lt;/p&gt;

&lt;h3&gt;
  
  
  Architecture highlights
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Procedural world (&lt;code&gt;worldMap.ts&lt;/code&gt;)&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Platforms are generated as connected climbable staircases separated by gaps, then pruned with a conservative walk/jump BFS so every remaining starlight spawn is actually collectible. The platforms are generated differently for every season for every play turn.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Season system (&lt;code&gt;seasonConfig.ts&lt;/code&gt;)&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Four seasons share the same passive darkness fill rate but ramp difficulty through Murkling speed, spawn rate, contact damage, and Striker presence (0 → 3 initial Strikers by Winter).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Depth sorting (&lt;code&gt;elementsConfig.ts&lt;/code&gt;)&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
World entities sort by feet Y + layer offset so characters on lower platforms render in front — important for a stacked platform world.&lt;/p&gt;

&lt;h3&gt;
  
  
  What I built on
&lt;/h3&gt;

&lt;p&gt;This project started from the official &lt;a href="https://github.com/phaserjs/template-react-ts" rel="noopener noreferrer"&gt;Phaser React TypeScript template&lt;/a&gt; (MIT). During the jam period (June 3–21, 2026) I replaced the template demo with original gameplay:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Story and Instructions scenes with narrative copy and animated previews&lt;/li&gt;
&lt;li&gt;Full platformer movement, combat, and enemy AI (patrol + Striker ranged attacks)&lt;/li&gt;
&lt;li&gt;Darkness/starlight HUD and full-screen overlay system&lt;/li&gt;
&lt;li&gt;Four-season progression with seasonal parallax backgrounds and tree art&lt;/li&gt;
&lt;li&gt;Procedural world generation with reachability guarantees&lt;/li&gt;
&lt;li&gt;Run/lifetime stats persisted in &lt;code&gt;localStorage&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devchallenge</category>
      <category>gamechallenge</category>
      <category>gamedev</category>
    </item>
    <item>
      <title>Pair - your personal stylist</title>
      <dc:creator>Dang Tran</dc:creator>
      <pubDate>Sat, 23 May 2026 11:31:53 +0000</pubDate>
      <link>https://dev.to/dang_tran_63f9ff8ece59c73/a-clothing-pairing-app-1egd</link>
      <guid>https://dev.to/dang_tran_63f9ff8ece59c73/a-clothing-pairing-app-1egd</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/google-gemma-2026-05-06"&gt;Gemma 4 Challenge: Build with Gemma 4&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;Pair is a personal stylist in your pocket. You take a photo of something you already own — a jacket, a pair of jeans, whatever — and the app finds you a complementary piece from a catalogue of 44,000 products. Then it generates an editorial fashion photo showing both items styled together on a model, so you can actually see how the outfit looks before you buy anything.&lt;/p&gt;

&lt;p&gt;The product catalogue is the Myntra fashion dataset (~44k products), available at &lt;a href="https://www.kaggle.com/datasets/paramaggarwal/fashion-product-images-dataset" rel="noopener noreferrer"&gt;kaggle.com/datasets/paramaggarwal/fashion-product-images-dataset&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The app is a full-stack TypeScript project — Vite + React on the frontend, Hono on Node.js on the backend. The interesting part is the AI pipeline: I send the uploaded image to Gemma 4, which returns structured JSON — category, gender, style tags, dominant colour. Then I query MongoDB with a $match + $sample aggregation to pull 30 random candidates from the right complementary category, and send those to Gemma 4 again to pick the best pairing. Finally, Gemini 2.5 Flash generates the editorial look image.&lt;/p&gt;

&lt;p&gt;Upload a photo&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fndq5d85n26unzp36fnn4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fndq5d85n26unzp36fnn4.png" alt="Upload a photo" width="800" height="615"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The app finds a match&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F90mgkbzo8spmc64m5cfz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F90mgkbzo8spmc64m5cfz.png" alt="The app finds a match" width="800" height="768"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Generate an editorial image of both items on a model&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnt99d4kd34u8s0dfxxur.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnt99d4kd34u8s0dfxxur.png" alt="Generate an editorial image of both items on a model" width="683" height="830"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/fzoA7PLkRK4"&gt;
  &lt;/iframe&gt;
&lt;br&gt;
&lt;/p&gt;
&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
      &lt;div class="c-embed__body flex items-center justify-between"&gt;
        &lt;a href="https://pair-vite.vercel.app/" rel="noopener noreferrer" class="c-link fw-bold flex items-center"&gt;
          &lt;span class="mr-2"&gt;pair-vite.vercel.app&lt;/span&gt;
          

        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/sea2709" rel="noopener noreferrer"&gt;
        sea2709
      &lt;/a&gt; / &lt;a href="https://github.com/sea2709/pair" rel="noopener noreferrer"&gt;
        pair
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Pair.&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;A clothing pairing app — upload a photo of one piece you own, get a complementary match from a curated catalogue, then see both styled together in an AI-generated editorial image.&lt;/p&gt;
&lt;p&gt;The product catalogue is the Myntra fashion dataset (~44k products), available at &lt;a href="https://www.kaggle.com/datasets/paramaggarwal/fashion-product-images-dataset" rel="nofollow noopener noreferrer"&gt;kaggle.com/datasets/paramaggarwal/fashion-product-images-dataset&lt;/a&gt;.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;How it works&lt;/h2&gt;
&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Upload&lt;/strong&gt; a photo of a top, bottom, shoes, or accessory — optionally add a hint if the photo contains multiple pieces&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Analyze&lt;/strong&gt; — Gemma 4 identifies the piece: category, gender, style, palette&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Confirm&lt;/strong&gt; — review the AI's interpretation; re-analyse with a corrected hint if needed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Match&lt;/strong&gt; — a complementary item is randomly sampled from the catalogue, then Gemma 4 picks the best fit&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lookbook&lt;/strong&gt; — Gemini generates a fashion editorial photo of both pieces styled on a model&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Stack&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Tech&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Frontend&lt;/td&gt;
&lt;td&gt;Vite + React + TypeScript + Tailwind CSS v4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Backend&lt;/td&gt;
&lt;td&gt;Hono on Node.js&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AI&lt;/td&gt;
&lt;td&gt;Google GenAI SDK (Gemma 4&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;…&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/sea2709/pair" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  How I Used Gemma 4
&lt;/h2&gt;

&lt;p&gt;Gemma 4 (gemma-4-31b-it) is used for two tasks where we need text output from a structured prompt:&lt;/p&gt;

&lt;p&gt;Clothing analysis — given an image, return a JSON object with category, gender, style, colors, etc.&lt;br&gt;
Match selection — given 30 product candidates from MongoDB, pick the best one and return a JSON object with the index, match score, and stylist note.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>gemmachallenge</category>
      <category>gemma</category>
    </item>
    <item>
      <title>Notion Bookmarks Manager</title>
      <dc:creator>Dang Tran</dc:creator>
      <pubDate>Sun, 29 Mar 2026 14:53:58 +0000</pubDate>
      <link>https://dev.to/dang_tran_63f9ff8ece59c73/notion-bookmark-manager-2gka</link>
      <guid>https://dev.to/dang_tran_63f9ff8ece59c73/notion-bookmark-manager-2gka</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/notion-2026-03-04"&gt;Notion MCP Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;The web content I browse every day is part of my personal knowledge base — but finding something I read weeks ago is frustratingly hard. I built this Chrome extension to solve that: it saves any page I bookmark directly to Notion, uses AI to generate a summary of the page content, and lets me search across everything I've saved using natural language.&lt;/p&gt;

&lt;h2&gt;
  
  
  Video Demo
&lt;/h2&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/GkO73fwNz_E"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Show us the code
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/sea2709" rel="noopener noreferrer"&gt;
        sea2709
      &lt;/a&gt; / &lt;a href="https://github.com/sea2709/notion-bookmark-manager" rel="noopener noreferrer"&gt;
        notion-bookmark-manager
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Notion Bookmark Manager&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;A Chrome extension that saves browser tabs to your Notion workspace, with folder organization, notes, AI-generated summaries, and AI-powered search.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Features&lt;/h2&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Save bookmarks&lt;/strong&gt; — Save the current tab to a Notion database with a title, URL, and optional notes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Folder tree&lt;/strong&gt; — Organize bookmarks into nested folders synced from Notion&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI summaries&lt;/strong&gt; — Optionally generate a page summary using Gemini AI based on a custom prompt&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Browse bookmarks&lt;/strong&gt; — View all your bookmarks grouped by folder in a collapsible tree&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Search&lt;/strong&gt; — Search your Notion bookmarks using natural language via Gemini AI and the Notion MCP&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Architecture&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;
&lt;pre class="notranslate"&gt;&lt;code&gt;Chrome Extension (Manifest V3)
├── popup/          UI for saving, browsing, and searching bookmarks
├── background/     Service worker — routes messages between popup and server
├── shared/         Shared types, constants, and chrome.storage helpers
└── dist/           Built output (load this directory in Chrome)
Local Server (Express)
└── server/         Handles all Notion API&lt;/code&gt;&lt;/pre&gt;…&lt;/div&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/sea2709/notion-bookmark-manager" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  How I Used Notion MCP
&lt;/h2&gt;

&lt;p&gt;MCP (Model Context Protocol) is used only in the searchBookmark function in server/notion-api.ts. It is not used anywhere else — all other Notion operations (create bookmark, fetch folders, etc.) go through the @notionhq/client SDK directly.&lt;/p&gt;

&lt;p&gt;How it works&lt;/p&gt;

&lt;p&gt;User presses Enter in search&lt;br&gt;
    → popup sends SEARCH_BOOKMARKS message&lt;br&gt;
    → service worker calls POST /call { tool: "search_bookmarks" }&lt;br&gt;
    → server calls searchBookmark()&lt;br&gt;
    → searchBookmark() connects to Notion MCP via npx mcp-remote&lt;br&gt;
    → Gemini AI uses the MCP tools to query Notion&lt;br&gt;
    → AI response text returned to popup&lt;/p&gt;

&lt;p&gt;The three components involved (MCP Client, mcpToTool adapter, Gemini)&lt;/p&gt;

&lt;p&gt;1.MCP Client (@modelcontextprotocol/sdk)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;notionClient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;McpClient&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;notion-client&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1.0.0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;transport&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;StdioClientTransport&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;npx&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;-y&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mcp-remote&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://mcp.notion.com/mcp&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;NOTION_TOKEN&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NOTION_API_KEY&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;notionClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;transport&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The MCP client spawns npx mcp-remote as a child process (stdio transport), which acts as a proxy connecting to Notion's official MCP server at &lt;a href="https://mcp.notion.com/mcp" rel="noopener noreferrer"&gt;https://mcp.notion.com/mcp&lt;/a&gt;. This exposes Notion's capabilities (search pages, read content, etc.) as MCP tools.&lt;/p&gt;

&lt;p&gt;2.mcpToTool adapter (@google/genai)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;mcpToTool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;notionClient&lt;/span&gt;&lt;span class="p"&gt;)],&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;mcpToTool wraps the MCP client so that Gemini can discover and call Notion's MCP tools automatically — Gemini decides which Notion tools to invoke based on the prompt.&lt;/p&gt;

&lt;p&gt;3.Gemini as the orchestrator&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`Search for pages under the database with the ID &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;databaseId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; mentioning '&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;keyword&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;'`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;ai&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generateContent&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;GEMINI_MODEL&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gemini-2.5-flash&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;contents&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;mcpToTool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;notionClient&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Gemini receives the natural language prompt and autonomously calls Notion MCP tools to find relevant pages, then summarizes the results into a text response.&lt;/p&gt;

&lt;p&gt;Why MCP for search vs. the SDK for everything else?&lt;br&gt;
The Notion SDK's search() API only matches page titles — it cannot search page body content. Notion's MCP server exposes richer capabilities including content-level search. By routing the query through Gemini + MCP, the search can find bookmarks by their AI-generated summary text, not just the title.&lt;/p&gt;

</description>
      <category>notionchallenge</category>
    </item>
    <item>
      <title>Apparel Shopping - Chatbot</title>
      <dc:creator>Dang Tran</dc:creator>
      <pubDate>Mon, 09 Feb 2026 04:08:41 +0000</pubDate>
      <link>https://dev.to/dang_tran_63f9ff8ece59c73/apparel-shopping-chatbot-4j2d</link>
      <guid>https://dev.to/dang_tran_63f9ff8ece59c73/apparel-shopping-chatbot-4j2d</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/algolia"&gt;Algolia Agent Studio Challenge&lt;/a&gt;: Consumer-Facing Conversational Experiences&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;A apparel shopping site with 2 pages (homepage and product details page) and a chatbot assistanting customers looking for products via conversation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://apparel-web.vercel.app/" rel="noopener noreferrer"&gt;https://apparel-web.vercel.app/&lt;/a&gt;&lt;br&gt;
Source code: &lt;a href="https://bitbucket.org/hdang2709/apparel/src/main/" rel="noopener noreferrer"&gt;https://bitbucket.org/hdang2709/apparel/src/main/&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Used Algolia Agent Studio
&lt;/h2&gt;

&lt;p&gt;I set up an application in Alogolia, create a new index and use the apparel sample dataset which has 2000 items.&lt;/p&gt;

&lt;p&gt;I configure searchable attributes and related facets.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;title&lt;/li&gt;
&lt;li&gt;description&lt;/li&gt;
&lt;li&gt;product_type&lt;/li&gt;
&lt;li&gt;color&lt;/li&gt;
&lt;li&gt;categories&lt;/li&gt;
&lt;li&gt;price&lt;/li&gt;
&lt;li&gt;tags&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgrvg3vy0ghh6v91hblt6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgrvg3vy0ghh6v91hblt6.png" alt=" " width="800" height="382"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Leverage InstantSearch.js widget to build the UI including a chat widget.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk4tj8437hxl9au881wfb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk4tj8437hxl9au881wfb.png" alt=" " width="698" height="713"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Fast Retrieval Matters
&lt;/h2&gt;

&lt;p&gt;The built-in chat widget in InstantSearch.js is very convenient. From the basic coding perspective, all you need are an agent ID and a container element to render to widget to build a chat interface that interacts with a generative AI assistant built with Algolia Agent Studio. And you can focus on constructing constructions and tools for the AI Agent.&lt;br&gt;
Algolia Studio also provides all conversations lists on the site with insights about how the response conducted (Reasoning and Tool used), which is very helpful to configure the Tools and setting up search attributes.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>algoliachallenge</category>
      <category>ai</category>
      <category>agents</category>
    </item>
    <item>
      <title>Apparel Shopping</title>
      <dc:creator>Dang Tran</dc:creator>
      <pubDate>Mon, 09 Feb 2026 03:09:10 +0000</pubDate>
      <link>https://dev.to/dang_tran_63f9ff8ece59c73/apparel-shopping-4m43</link>
      <guid>https://dev.to/dang_tran_63f9ff8ece59c73/apparel-shopping-4m43</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/algolia"&gt;Algolia Agent Studio Challenge&lt;/a&gt;: Consumer-Facing Non-Conversational Experiences&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;A apparel shopping site with 2 pages (homepage and product details page) and a chatbot assistanting customers looking for products via conversation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://apparel-web.vercel.app/" rel="noopener noreferrer"&gt;https://apparel-web.vercel.app/&lt;/a&gt;&lt;br&gt;
Source code: &lt;a href="https://bitbucket.org/hdang2709/apparel/src/main/" rel="noopener noreferrer"&gt;https://bitbucket.org/hdang2709/apparel/src/main/&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Used Algolia Agent Studio
&lt;/h2&gt;

&lt;p&gt;I set up an application in Alogolia, create a new index and use the apparel sample dataset which has 2000 items.&lt;/p&gt;

&lt;p&gt;I configure searchable attributes and related facets.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;title&lt;/li&gt;
&lt;li&gt;description&lt;/li&gt;
&lt;li&gt;product_type&lt;/li&gt;
&lt;li&gt;color&lt;/li&gt;
&lt;li&gt;categories&lt;/li&gt;
&lt;li&gt;price&lt;/li&gt;
&lt;li&gt;tags&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgrvg3vy0ghh6v91hblt6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgrvg3vy0ghh6v91hblt6.png" alt=" " width="800" height="382"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Leverage InstantSearch.js widget to build the UI for list products, refinement, search box, auto complete, chat, etc.&lt;/p&gt;

&lt;p&gt;With a traditional shopping site, customers use existing filter widgets to find their products. I added a tweak to let customers using a prompt to filter products by leveraging Generative AI in Algolia Agent Studio. I set up 2 agents, one for the chat and one for the filter functionality. The 2 agents are pretty similar, but the filter agent will not response with follow up questions to clarify some details.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw7hllrnidkhxrkdja4k4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw7hllrnidkhxrkdja4k4.png" alt=" " width="593" height="456"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4bsin1inuui8qagoc86r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4bsin1inuui8qagoc86r.png" alt=" " width="800" height="574"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3acpn5ks60mne73ccxxe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3acpn5ks60mne73ccxxe.png" alt=" " width="800" height="216"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fif0y5ccpg521aj4vrs45.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fif0y5ccpg521aj4vrs45.png" alt=" " width="800" height="748"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Fast Retrieval Matters
&lt;/h2&gt;

&lt;p&gt;Algolia agent can form a query based on the user's prompt or conversation. The query is flexible depending on the indexed data, configurable search attributes.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>algoliachallenge</category>
      <category>ai</category>
      <category>agents</category>
    </item>
  </channel>
</rss>
