<?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: Iresh Madushanka</title>
    <description>The latest articles on DEV Community by Iresh Madushanka (@iresh96).</description>
    <link>https://dev.to/iresh96</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%2F242221%2Ffb4c0cf2-a238-4683-938a-8d6817102c1a.jpeg</url>
      <title>DEV Community: Iresh Madushanka</title>
      <link>https://dev.to/iresh96</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/iresh96"/>
    <language>en</language>
    <item>
      <title>React Google Places Autocomplete – Modern, TypeScript-Friendly Component</title>
      <dc:creator>Iresh Madushanka</dc:creator>
      <pubDate>Sun, 21 Dec 2025 14:31:35 +0000</pubDate>
      <link>https://dev.to/iresh96/react-google-places-autocomplete-modern-typescript-friendly-component-2f4d</link>
      <guid>https://dev.to/iresh96/react-google-places-autocomplete-modern-typescript-friendly-component-2f4d</guid>
      <description>&lt;h1&gt;
  
  
  React Google Places Autocomplete – Modern, TypeScript-Friendly Component
&lt;/h1&gt;

&lt;p&gt;If you’ve ever built a React app that needs &lt;strong&gt;location inputs&lt;/strong&gt;, you know how tricky Google Places Autocomplete can be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Legacy libraries are often unmaintained.&lt;/li&gt;
&lt;li&gt;Google recently introduced the &lt;strong&gt;AutocompleteSuggestion API&lt;/strong&gt;, leaving many libraries behind.&lt;/li&gt;
&lt;li&gt;Managing session tokens, debouncing, and error handling can get messy fast.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s why I created &lt;strong&gt;&lt;a href="https://github.com/iresh96/react-google-places-autocomplete-modern" rel="noopener noreferrer"&gt;react-google-places-autocomplete-modern&lt;/a&gt;&lt;/strong&gt; — a &lt;strong&gt;production-ready React component&lt;/strong&gt; that handles everything cleanly.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why This Component Exists
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Supports the &lt;strong&gt;new AutocompleteSuggestion API&lt;/strong&gt; (recommended by Google)&lt;/li&gt;
&lt;li&gt;Automatically falls back to the legacy &lt;code&gt;AutocompleteService&lt;/code&gt; if needed&lt;/li&gt;
&lt;li&gt;Handles session tokens, debouncing, and errors automatically&lt;/li&gt;
&lt;li&gt;Works with &lt;strong&gt;React + Next.js&lt;/strong&gt;, TypeScript, and modern builds&lt;/li&gt;
&lt;li&gt;Fully controlled component for forms&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In short, it lets you focus on &lt;strong&gt;UX&lt;/strong&gt;, not Google Maps quirks.&lt;/p&gt;




&lt;h2&gt;
  
  
  Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Country &amp;amp; language restrictions&lt;/li&gt;
&lt;li&gt;Debounced inputs to reduce API calls&lt;/li&gt;
&lt;li&gt;Async script loading (&lt;code&gt;v=weekly&amp;amp;loading=async&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Custom rendering of suggestions&lt;/li&gt;
&lt;li&gt;Defensive error handling&lt;/li&gt;
&lt;li&gt;TypeScript-ready&lt;/li&gt;
&lt;li&gt;Tree-shakeable, minimal footprint&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🛠 Installation
&lt;/h2&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;react-google-places-autocomplete-modern
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Peer dependencies: &lt;code&gt;react&lt;/code&gt; and &lt;code&gt;react-dom&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  📦 Basic Usage
&lt;/h2&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;useState&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;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;LocationAutocomplete&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;react-google-places-autocomplete-modern&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Example&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&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;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setValue&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&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="nc"&gt;LocationAutocomplete&lt;/span&gt;
      &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;setValue&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;onSelect&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="nx"&gt;place&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;place&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;
  &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;h2&gt;
  
  
  Advanced Usage
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;LocationAutocomplete&lt;/span&gt;
  &lt;span class="na"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&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;NEXT_PUBLIC_MAPS_KEY&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;setValue&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;onSelect&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="nx"&gt;place&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;place&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;countries&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;us&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="na"&gt;language&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt;
  &lt;span class="na"&gt;debounceMs&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;250&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;minLength&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;autoClearSuggestions&lt;/span&gt;
  &lt;span class="na"&gt;renderSuggestion&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="nx"&gt;s&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="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;strong&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;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;structuredFormatting&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;mainText&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;description&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;strong&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;small&lt;/span&gt; &lt;span class="na"&gt;style&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="na"&gt;marginLeft&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;6&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;
        &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;structuredFormatting&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;secondaryText&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;small&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;span class="si"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;Next.js note:&lt;/strong&gt;&lt;br&gt;
Use &lt;code&gt;"use client"&lt;/code&gt; or dynamic import with &lt;code&gt;ssr: false&lt;/code&gt; to ensure the component renders only in the browser.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🔒 Security &amp;amp; Performance
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;API keys are never embedded in the package&lt;/li&gt;
&lt;li&gt;Debouncing + session tokens reduce quota usage&lt;/li&gt;
&lt;li&gt;Cleans up timers and listeners on unmount&lt;/li&gt;
&lt;li&gt;Compatible with modern React practices&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Google Maps Setup
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Enable &lt;strong&gt;Places API&lt;/strong&gt; and &lt;strong&gt;Maps JavaScript API&lt;/strong&gt; in Google Cloud&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;HTTP referrer-restricted keys&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Ensure billing is enabled&lt;/li&gt;
&lt;li&gt;Optional: manually load the script or let the component handle it&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/iresh96/react-google-places-autocomplete-modern" rel="noopener noreferrer"&gt;https://github.com/iresh96/react-google-places-autocomplete-modern&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;npm: &lt;a href="https://www.npmjs.com/package/react-google-places-autocomplete-modern" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/react-google-places-autocomplete-modern&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Why You’ll Love It
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Saves you from messy Google Maps setup&lt;/li&gt;
&lt;li&gt;Works reliably even with the new Google API&lt;/li&gt;
&lt;li&gt;Fully typed and modern React friendly&lt;/li&gt;
&lt;li&gt;Easy to customize and extend&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;If you’re building a React app with &lt;strong&gt;location search&lt;/strong&gt;, this is the package I wish I had when I started.&lt;/p&gt;




&lt;p&gt;💡 &lt;strong&gt;Pro tip:&lt;/strong&gt;&lt;br&gt;
Combine with your UI library (Tailwind, Material UI, or Chakra) for fully styled suggestions in minutes.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>react</category>
      <category>javascript</category>
      <category>typescript</category>
    </item>
  </channel>
</rss>
