<?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: Alex Amancio (Candoa)</title>
    <description>The latest articles on DEV Community by Alex Amancio (Candoa) (@alex_amanciocandoa_49c).</description>
    <link>https://dev.to/alex_amanciocandoa_49c</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3232782%2F85e5c8f2-b6f3-4a1b-adef-51aaa4309a0c.png</url>
      <title>DEV Community: Alex Amancio (Candoa)</title>
      <link>https://dev.to/alex_amanciocandoa_49c</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/alex_amanciocandoa_49c"/>
    <language>en</language>
    <item>
      <title>I built a headless React chatbot widget for full UI control</title>
      <dc:creator>Alex Amancio (Candoa)</dc:creator>
      <pubDate>Sat, 31 May 2025 18:15:23 +0000</pubDate>
      <link>https://dev.to/alex_amanciocandoa_49c/i-built-a-headless-react-chatbot-widget-for-full-ui-control-5f9n</link>
      <guid>https://dev.to/alex_amanciocandoa_49c/i-built-a-headless-react-chatbot-widget-for-full-ui-control-5f9n</guid>
      <description>&lt;p&gt;🧱 I built a headless React chatbot widget so devs can fully control the UI&lt;br&gt;
Most chatbot widgets come bloated with their own styling and markup. I wanted something I could completely control — so I built my own.&lt;/p&gt;

&lt;p&gt;👉 @candoa/chatbot is a headless React chatbot widget built for devs who love:&lt;/p&gt;

&lt;p&gt;full UI freedom,&lt;/p&gt;

&lt;p&gt;TailwindCSS,&lt;/p&gt;

&lt;p&gt;React Hooks,&lt;/p&gt;

&lt;p&gt;and minimal dependencies.&lt;/p&gt;

&lt;p&gt;⚡ Key Features&lt;br&gt;
Headless architecture (bring your own UI)&lt;/p&gt;

&lt;p&gt;Conversation persistence (localStorage)&lt;/p&gt;

&lt;p&gt;Greeting messages&lt;/p&gt;

&lt;p&gt;Typing indicators&lt;/p&gt;

&lt;p&gt;Error handling&lt;/p&gt;

&lt;p&gt;Demo GIF: &lt;a href="https://candoa-public.s3.us-east-2.amazonaws.com/chatbot-ezgif.com-loop-count.gif" rel="noopener noreferrer"&gt;https://candoa-public.s3.us-east-2.amazonaws.com/chatbot-ezgif.com-loop-count.gif&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🛠️ Install&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; @candoa/chatbot
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  or
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn add @candoa/chatbot
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;📦 Example&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useChatbot&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@candoa/chatbot&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;actions&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useChatbot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;your-project-id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;actions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Send&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I’m a solo dev working on this. Would love your feedback or ideas!&lt;br&gt;
GitHub: &lt;a href="https://github.com/aamancio/candoa-chatbot" rel="noopener noreferrer"&gt;https://github.com/aamancio/candoa-chatbot&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>opensource</category>
      <category>tailwindcss</category>
    </item>
  </channel>
</rss>
