<?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: Smarteyeapps.com</title>
    <description>The latest articles on DEV Community by Smarteyeapps.com (@smarteye_apps).</description>
    <link>https://dev.to/smarteye_apps</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%2F4045891%2F350a12e2-1d92-4504-94a2-a0cd9adf683f.jpg</url>
      <title>DEV Community: Smarteyeapps.com</title>
      <link>https://dev.to/smarteye_apps</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/smarteye_apps"/>
    <language>en</language>
    <item>
      <title>Build a Free Online Email Extractor with JavaScript</title>
      <dc:creator>Smarteyeapps.com</dc:creator>
      <pubDate>Tue, 18 Aug 2026 02:31:29 +0000</pubDate>
      <link>https://dev.to/smarteye_apps/build-a-free-online-email-extractor-with-javascript-20ob</link>
      <guid>https://dev.to/smarteye_apps/build-a-free-online-email-extractor-with-javascript-20ob</guid>
      <description>&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%2Fw0cqa2f5of86fejal81d.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%2Fw0cqa2f5of86fejal81d.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;br&gt;
Finding email addresses inside a large block of text sounds simple—until you have to manually search through hundreds or thousands of lines.&lt;/p&gt;

&lt;p&gt;That's why I built Online Email Extractor Free, a small browser-based tool that extracts email addresses from text, removes duplicates, and lets users copy, send, or download the results as CSV.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The goal was simple:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Paste text → Extract emails → Use the results&lt;br&gt;
What the tool does&lt;br&gt;
The tool accepts unstructured text such as:&lt;br&gt;
Meeting notes&lt;br&gt;
Contact lists&lt;br&gt;
Business information&lt;br&gt;
Copied web content&lt;br&gt;
Documents&lt;br&gt;
Code or logs&lt;br&gt;
Research notes&lt;br&gt;
After clicking Extract Emails, the application identifies email addresses and displays them in a clean grid.&lt;br&gt;
For example, given:&lt;br&gt;
Meeting Notes - Q3 Strategy Alignment&lt;/p&gt;

&lt;p&gt;John from marketing (&lt;a href="mailto:john.doe@example.com"&gt;john.doe@example.com&lt;/a&gt;) presented&lt;br&gt;
the new campaign.&lt;/p&gt;

&lt;p&gt;Please contact his assistant at&lt;br&gt;
&lt;a href="mailto:sarah.smith123@company.co.uk"&gt;sarah.smith123@company.co.uk&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Send the API documentation to&lt;br&gt;
&lt;a href="mailto:admin@dev-ops.tech"&gt;admin@dev-ops.tech&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;CC accounting at &lt;a href="mailto:support@billing.net"&gt;support@billing.net&lt;/a&gt;.&lt;br&gt;
The extractor produces:&lt;br&gt;
&lt;a href="mailto:john.doe@example.com"&gt;john.doe@example.com&lt;/a&gt;&lt;br&gt;
&lt;a href="mailto:sarah.smith123@company.co.uk"&gt;sarah.smith123@company.co.uk&lt;/a&gt;&lt;br&gt;
&lt;a href="mailto:admin@dev-ops.tech"&gt;admin@dev-ops.tech&lt;/a&gt;&lt;br&gt;
&lt;a href="mailto:support@billing.net"&gt;support@billing.net&lt;/a&gt;&lt;br&gt;
Duplicate addresses are removed automatically.&lt;br&gt;
Why build it entirely in the browser?&lt;br&gt;
One of the main decisions was to make the extraction process client-side.&lt;br&gt;
There is no reason to upload a user's text to a server just to find email addresses.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The basic architecture is:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;User Input&lt;br&gt;
    ↓&lt;br&gt;
Browser JavaScript&lt;br&gt;
    ↓&lt;br&gt;
Find Email Addresses&lt;br&gt;
    ↓&lt;br&gt;
Normalize &amp;amp; Deduplicate&lt;br&gt;
    ↓&lt;br&gt;
Display Results&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This provides two important benefits:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Privacy&lt;br&gt;
The user's pasted content can remain on their device.&lt;br&gt;
Speed&lt;br&gt;
There is no API request required for the extraction itself.&lt;br&gt;
For a small utility like this, browser-based processing is a good fit.&lt;br&gt;
Extracting Email Addresses with JavaScript&lt;br&gt;
The core of the application can be implemented with a regular expression.&lt;br&gt;
A simple implementation looks like this:&lt;br&gt;
const emailRegex = /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}/g;&lt;/p&gt;

&lt;p&gt;const emails = text.match(emailRegex) || [];&lt;br&gt;
This searches the supplied text for strings that resemble email addresses.&lt;br&gt;
For example:&lt;br&gt;
const text = &lt;code&gt;&lt;br&gt;
    Contact john@example.com&lt;br&gt;
    or sales@example.com.&lt;br&gt;
    You can also reach john@example.com.&lt;br&gt;
&lt;/code&gt;;&lt;/p&gt;

&lt;p&gt;const matches = text.match(emailRegex) || [];&lt;/p&gt;

&lt;p&gt;console.log(matches);&lt;br&gt;
The result contains:&lt;br&gt;
[&lt;br&gt;
    "&lt;a href="mailto:john@example.com"&gt;john@example.com&lt;/a&gt;",&lt;br&gt;
    "&lt;a href="mailto:sales@example.com"&gt;sales@example.com&lt;/a&gt;",&lt;br&gt;
    "&lt;a href="mailto:john@example.com"&gt;john@example.com&lt;/a&gt;"&lt;br&gt;
]&lt;br&gt;
But we don't want duplicate results.&lt;br&gt;
Removing Duplicate Email Addresses&lt;br&gt;
JavaScript's Set makes deduplication straightforward:&lt;br&gt;
const uniqueEmails = [...new Set(matches)];&lt;br&gt;
Now the result becomes:&lt;br&gt;
[&lt;br&gt;
    "&lt;a href="mailto:john@example.com"&gt;john@example.com&lt;/a&gt;",&lt;br&gt;
    "&lt;a href="mailto:sales@example.com"&gt;sales@example.com&lt;/a&gt;"&lt;br&gt;
]&lt;br&gt;
I also normalize the values before deduplication:&lt;br&gt;
const uniqueEmails = [&lt;br&gt;
    ...new Set(&lt;br&gt;
        matches.map(email =&amp;gt; email.trim().toLowerCase())&lt;br&gt;
    )&lt;br&gt;
];&lt;br&gt;
This prevents variations such as:&lt;br&gt;
&lt;a href="mailto:John@example.com"&gt;John@example.com&lt;/a&gt;&lt;br&gt;
&lt;a href="mailto:john@example.com"&gt;john@example.com&lt;/a&gt;&lt;br&gt;
 &lt;a href="mailto:JOHN@example.com"&gt;JOHN@example.com&lt;/a&gt;&lt;br&gt;
from appearing as separate results.&lt;br&gt;
Displaying the Results&lt;br&gt;
The extracted addresses can then be rendered as a simple grid.&lt;br&gt;
Each result provides useful actions:&lt;br&gt;
┌──────────────────────────────────────────┐&lt;br&gt;
│ &lt;a href="mailto:john@example.com"&gt;john@example.com&lt;/a&gt;             Send   Copy │&lt;br&gt;
└──────────────────────────────────────────┘&lt;br&gt;
The interface is intentionally simple.&lt;br&gt;
Users don't need to understand how the extraction works. They just need to get their email addresses quickly.&lt;br&gt;
Copying an Individual Email&lt;br&gt;
The Clipboard API makes individual copying easy:&lt;br&gt;
async function copyEmail(email) {&lt;br&gt;
    await navigator.clipboard.writeText(email);&lt;br&gt;
}&lt;br&gt;
For example:&lt;br&gt;
&lt;br&gt;
    Copy&lt;br&gt;
&lt;br&gt;
For copying all extracted addresses:&lt;br&gt;
async function copyAllEmails(emails) {&lt;br&gt;
    await navigator.clipboard.writeText(&lt;br&gt;
        emails.join('\n')&lt;br&gt;
    );&lt;br&gt;
}&lt;br&gt;
The user can then paste the list into another application.&lt;br&gt;
Sending an Email&lt;br&gt;
Another small but useful feature is the Send button.&lt;br&gt;
Instead of implementing an email delivery system, the application can use the user's default email client:&lt;br&gt;
function sendEmail(email) {&lt;br&gt;
    window.location.href = &lt;code&gt;mailto:${email}&lt;/code&gt;;&lt;br&gt;
}&lt;br&gt;
This keeps the feature lightweight.&lt;br&gt;
The extractor doesn't need:&lt;br&gt;
SMTP configuration&lt;br&gt;
Email provider integration&lt;br&gt;
User accounts&lt;br&gt;
Email infrastructure&lt;br&gt;
It simply hands the address to the user's email client.&lt;br&gt;
Downloading the Results as CSV&lt;br&gt;
The extracted emails can also be exported directly from the browser.&lt;br&gt;
For example:&lt;br&gt;
function downloadCSV(emails) {&lt;br&gt;
    const csv = [&lt;br&gt;
        'Email',&lt;br&gt;
        ...emails&lt;br&gt;
    ].join('\n');&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const blob = new Blob([csv], {
    type: 'text/csv;charset=utf-8;'
});

const url = URL.createObjectURL(blob);

const link = document.createElement('a');
link.href = url;
link.download = 'extracted-emails.csv';

document.body.appendChild(link);
link.click();
link.remove();

URL.revokeObjectURL(url);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;br&gt;
This creates the CSV locally without requiring a backend export endpoint.&lt;br&gt;
Keeping the Interface Simple&lt;br&gt;
The biggest challenge with utility tools isn't necessarily the JavaScript.&lt;br&gt;
It's the UI.&lt;br&gt;
For this type of application, the workflow should be obvious immediately:&lt;br&gt;
┌─────────────────────────────────────────────┐&lt;br&gt;
│                                             │&lt;br&gt;
│ Paste your text here...                     │&lt;br&gt;
│                                             │&lt;br&gt;
│                                             │&lt;br&gt;
└─────────────────────────────────────────────┘&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                [ Extract Emails ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Extracted Emails (9)&lt;/p&gt;

&lt;p&gt;┌────────────────────┐ ┌────────────────────┐ ┌────────────────────┐&lt;br&gt;
│ &lt;a href="mailto:john@example.com"&gt;john@example.com&lt;/a&gt;   │ │ &lt;a href="mailto:sales@example.com"&gt;sales@example.com&lt;/a&gt;  │ │ &lt;a href="mailto:info@example.com"&gt;info@example.com&lt;/a&gt;   │&lt;br&gt;
│             Send Copy│ │            Send Copy│ │            Send Copy│&lt;br&gt;
└────────────────────┘ └────────────────────┘ └────────────────────┘&lt;/p&gt;

&lt;p&gt;[ Copy All Emails ]          [ Download as CSV ]&lt;/p&gt;

&lt;p&gt;There shouldn't be unnecessary steps between the user and the result.&lt;/p&gt;

&lt;p&gt;Why I Made It Free&lt;br&gt;
This is part of a broader idea behind Smarteyeapps.&lt;br&gt;
Instead of building only large SaaS applications, we're experimenting with small, focused web applications that solve one specific problem.&lt;br&gt;
The email extractor is a good example:&lt;br&gt;
One problem. One tool. No complicated setup.&lt;br&gt;
The tool is free to use, with no registration required.&lt;br&gt;
Security and Privacy&lt;br&gt;
Because the extraction can happen entirely in the browser, sensitive text doesn't need to be sent to an application server.&lt;br&gt;
The architecture can therefore be:&lt;br&gt;
                ┌─────────────────┐&lt;br&gt;
                │     Browser     │&lt;br&gt;
                │                 │&lt;br&gt;
Input ─────────►│ Email Extractor │&lt;br&gt;
                │      JavaScript │&lt;br&gt;
                │                 │&lt;br&gt;
                └─────────────────┘&lt;br&gt;
                         │&lt;br&gt;
                         ▼&lt;br&gt;
                  Extracted Emails&lt;br&gt;
There is no server-side processing required for the core extraction functionality.&lt;br&gt;
Of course, if you add analytics, logging, authentication, or other external services, those should be evaluated separately from the extraction process.&lt;br&gt;
A Small Tool Can Still Be Useful&lt;br&gt;
One thing I like about building micro-apps is that the application doesn't need dozens of features to be useful.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The entire workflow can be summarized in three steps:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Paste
Paste text containing email addresses.&lt;/li&gt;
&lt;li&gt;Extract
Find email addresses and remove duplicates.&lt;/li&gt;
&lt;li&gt;Use
Copy, send, or download the results.
That's it.
Try the Tool
I've made the Online Email Extractor Free available as a free browser-based utility.
Extract email addresses from text without manually searching through the content.
👉 &lt;a href="https://smarteyeapps.com/email-extractor" rel="noopener noreferrer"&gt;https://smarteyeapps.com/email-extractor&lt;/a&gt;
If you build similar browser-based utilities, I'd be interested in hearing what approaches you use for client-side text processing.&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>frontend</category>
      <category>javascript</category>
      <category>tools</category>
      <category>webdev</category>
    </item>
    <item>
      <title>I Built a Free QR Menu SaaS with Laravel 12 &amp; React — Here's What I Learned</title>
      <dc:creator>Smarteyeapps.com</dc:creator>
      <pubDate>Tue, 28 Jul 2026 16:11:32 +0000</pubDate>
      <link>https://dev.to/smarteye_apps/i-built-a-free-qr-menu-saas-with-laravel-12-react-heres-what-i-learned-1h3l</link>
      <guid>https://dev.to/smarteye_apps/i-built-a-free-qr-menu-saas-with-laravel-12-react-heres-what-i-learned-1h3l</guid>
      <description>&lt;p&gt;A few weeks ago, I challenged myself to build another micro SaaS.&lt;br&gt;
Instead of creating another AI-powered tool, I wanted to solve a simple, real-world problem.&lt;br&gt;
Restaurant owners still spend time and money printing menus every time prices change or new dishes are added.&lt;br&gt;
The solution seemed straightforward: build a QR Menu Builder that lets restaurants manage their menu online and generate a QR code for customers.&lt;br&gt;
The idea was simple.&lt;br&gt;
Building it wasn't.&lt;br&gt;
In this article, I'll share some of the architectural decisions, challenges, and lessons I learned while building it with Laravel 12, React, Inertia.js, and Tailwind CSS.&lt;br&gt;
The Tech Stack&lt;br&gt;
I wanted a stack that I already trusted.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Backend&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Laravel 12&lt;br&gt;
PHP 8.4&lt;br&gt;
MySQL&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Frontend&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;React&lt;br&gt;
Inertia.js&lt;br&gt;
Tailwind CSS&lt;br&gt;
Vite&lt;/p&gt;

&lt;p&gt;Laravel remains my first choice because it allows me to move quickly without sacrificing code organization.&lt;br&gt;
React + Inertia gives me a modern SPA experience without maintaining separate frontend and backend applications.&lt;br&gt;
For a solo developer building multiple micro SaaS products, this combination has been extremely productive.&lt;br&gt;
Designing the Database&lt;br&gt;
One mistake I've made in previous projects was coupling everything together.&lt;br&gt;
This time I kept the database simple and modular.&lt;br&gt;
restaurants&lt;br&gt;
    ├── categories&lt;br&gt;
    │      └── menu_items&lt;br&gt;
    │&lt;br&gt;
    ├── qr_codes&lt;br&gt;
    │&lt;br&gt;
    └── scans&lt;br&gt;
The relationships are straightforward.&lt;br&gt;
Restaurant&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;hasMany Categories
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Category&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;hasMany MenuItems
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Restaurant&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;hasMany Scans
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Keeping the hierarchy shallow made queries easier and reduced unnecessary joins.&lt;br&gt;
Why I Didn't Store Everything in JSON&lt;br&gt;
It can be tempting to store the entire menu in a JSON column.&lt;br&gt;
Something like this:&lt;br&gt;
{&lt;br&gt;
  "categories": [&lt;br&gt;
    {&lt;br&gt;
      "name": "Starters",&lt;br&gt;
      "items": [...]&lt;br&gt;
    }&lt;br&gt;
  ]&lt;br&gt;
}&lt;br&gt;
While this works for small applications, it quickly becomes difficult when you need:&lt;br&gt;
search&lt;br&gt;
analytics&lt;br&gt;
ordering&lt;br&gt;
filtering&lt;br&gt;
reporting&lt;br&gt;
Using proper relational tables makes future features much easier to implement.&lt;br&gt;
Generating QR Codes&lt;br&gt;
QR generation turned out to be one of the easiest parts.&lt;br&gt;
Using Laravel packages, generating a QR code is surprisingly simple.&lt;br&gt;
$url = route('restaurant.menu', $restaurant-&amp;gt;slug);&lt;/p&gt;

&lt;p&gt;QrCode::format('svg')&lt;br&gt;
    -&amp;gt;size(300)&lt;br&gt;
    -&amp;gt;generate($url);&lt;br&gt;
I chose SVG instead of PNG because:&lt;br&gt;
smaller file size&lt;br&gt;
scales perfectly&lt;br&gt;
looks sharper when printed&lt;br&gt;
easier to embed&lt;br&gt;
Routing the Public Menu&lt;br&gt;
One decision I made early was separating the public menu from the dashboard.&lt;br&gt;
Instead of URLs like&lt;br&gt;
/restaurant/25/menu&lt;br&gt;
I switched to&lt;br&gt;
/menu/the-coffee-house&lt;br&gt;
Using slugs provides cleaner URLs and is much better for SEO.&lt;br&gt;
Laravel makes route model binding with slugs incredibly easy.&lt;br&gt;
Route::get('/menu/{restaurant:slug}', ...);&lt;br&gt;
Building the Dashboard&lt;br&gt;
The dashboard only has a few sections.&lt;br&gt;
Restaurant&lt;/p&gt;

&lt;p&gt;Categories&lt;/p&gt;

&lt;p&gt;Menu Items&lt;/p&gt;

&lt;p&gt;QR Code&lt;/p&gt;

&lt;p&gt;Settings&lt;/p&gt;

&lt;p&gt;Analytics&lt;br&gt;
I intentionally avoided adding dozens of menus and settings.&lt;br&gt;
Restaurant owners don't want complicated software.&lt;br&gt;
They just want to:&lt;br&gt;
update prices&lt;br&gt;
add dishes&lt;br&gt;
hide unavailable items&lt;br&gt;
print their QR code&lt;br&gt;
Sometimes fewer features create a better product.&lt;br&gt;
Mobile First&lt;br&gt;
One lesson I've learned from previous SaaS projects:&lt;br&gt;
Never treat mobile as an afterthought.&lt;br&gt;
Restaurant owners often update their menu from their phones.&lt;br&gt;
Every page was designed to work comfortably on smaller screens.&lt;br&gt;
Tailwind CSS made responsive layouts much easier than my previous Bootstrap projects.&lt;br&gt;
Performance Considerations&lt;br&gt;
Even a simple menu can contain hundreds of items.&lt;br&gt;
To keep loading fast, I:&lt;br&gt;
eager loaded relationships&lt;br&gt;
optimized database indexes&lt;br&gt;
cached public menus&lt;br&gt;
optimized images&lt;br&gt;
lazy loaded admin components&lt;br&gt;
The public menu should feel almost instant because customers scan it while sitting at a table.&lt;br&gt;
SEO Matters More Than I Expected&lt;br&gt;
Initially, I treated this like a typical SaaS landing page.&lt;br&gt;
Then I realized most restaurant owners search for phrases like:&lt;br&gt;
Free QR Menu&lt;br&gt;
QR Menu Builder&lt;br&gt;
Digital Restaurant Menu&lt;br&gt;
Restaurant QR Code Menu&lt;br&gt;
So I spent time improving:&lt;br&gt;
semantic HTML&lt;br&gt;
structured headings&lt;br&gt;
FAQs&lt;br&gt;
landing page content&lt;br&gt;
internal linking&lt;br&gt;
metadata&lt;br&gt;
Good SEO takes longer than building features—but it's worth the investment.&lt;br&gt;
What I'd Do Differently&lt;br&gt;
If I started again, I'd probably build:&lt;br&gt;
multi-language menus from day one&lt;br&gt;
menu templates earlier&lt;br&gt;
image optimization pipeline&lt;br&gt;
analytics dashboard sooner&lt;br&gt;
Building real software teaches you things that planning never will.&lt;br&gt;
What's Next?&lt;br&gt;
Some features I'm currently working on include:&lt;br&gt;
📊 Scan analytics&lt;br&gt;
📱 WhatsApp ordering&lt;br&gt;
🍽️ Multiple menu templates&lt;br&gt;
🌍 Multi-language support&lt;br&gt;
📅 Pre-order menus&lt;br&gt;
⭐ Featured dishes&lt;br&gt;
I'm trying to keep the product simple while solving genuine problems for restaurant owners.&lt;br&gt;
Final Thoughts&lt;br&gt;
Building small SaaS products has become one of my favorite ways to learn.&lt;br&gt;
Every project forces me to think about architecture, UX, SEO, performance, and deployment—not just writing code.&lt;br&gt;
This QR Menu Builder started as a weekend idea and has grown into a practical project where I can experiment with Laravel, React, and product development.&lt;br&gt;
If you're building your own micro SaaS, I'd love to hear how you structure your projects and what stack you're using.&lt;br&gt;
You can also check out the project here:&lt;br&gt;
👉 &lt;a href="https://www.smarteyeapps.com/qr-menu" rel="noopener noreferrer"&gt;https://www.smarteyeapps.com/qr-menu&lt;/a&gt;&lt;br&gt;
Tags: &lt;/p&gt;

</description>
      <category>laravel</category>
      <category>react</category>
      <category>saas</category>
    </item>
    <item>
      <title>Stop Copying Phone Numbers One by One: Build a Simple WhatsApp Contact Extractor</title>
      <dc:creator>Smarteyeapps.com</dc:creator>
      <pubDate>Fri, 24 Jul 2026 16:56:40 +0000</pubDate>
      <link>https://dev.to/smarteye_apps/stop-copying-phone-numbers-one-by-one-build-a-simple-whatsapp-contact-extractor-2h0b</link>
      <guid>https://dev.to/smarteye_apps/stop-copying-phone-numbers-one-by-one-build-a-simple-whatsapp-contact-extractor-2h0b</guid>
      <description>&lt;p&gt;As a developer, I often find myself collecting contacts from business directories, PDFs, websites, and documents.&lt;br&gt;
The workflow was always the same:&lt;br&gt;
Copy a phone number&lt;br&gt;
Save it as a contact (or copy it again)&lt;br&gt;
Open WhatsApp&lt;br&gt;
Send a message&lt;br&gt;
Repeat...&lt;/p&gt;

&lt;p&gt;After doing this hundreds of times, I decided to build a small tool to automate the repetitive part.&lt;br&gt;
The Idea&lt;br&gt;
The tool accepts any block of text and automatically extracts phone numbers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Once extracted, each number can be used to:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;💬 Open a WhatsApp chat&lt;br&gt;
📞 Make a phone call&lt;br&gt;
📩 Send an SMS&lt;br&gt;
📥 Export contacts to CSV&lt;/p&gt;

&lt;p&gt;No manual copy-paste for every contact.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example Workflow&lt;/strong&gt;&lt;br&gt;
Copy text from a business directory, website, or PDF.&lt;br&gt;
Paste it into the tool.&lt;br&gt;
Click Extract Mobile Numbers.&lt;br&gt;
Start messaging contacts immediately.&lt;br&gt;
How It Works&lt;br&gt;
The core logic is intentionally simple:&lt;br&gt;
Parse plain text&lt;/p&gt;

&lt;p&gt;Detect phone numbers using pattern matching&lt;br&gt;
Remove duplicates&lt;br&gt;
Normalize numbers&lt;br&gt;
Generate action buttons for WhatsApp, Call, SMS, and CSV export&lt;br&gt;
Everything runs directly in the browser, so there's nothing to install.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Remove duplicates&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This isn't a complex SaaS or an AI-powered application.&lt;br&gt;
It's a small utility that solves a real problem I faced almost every day.&lt;br&gt;
Sometimes the simplest tools save the most time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's Next?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I'm planning to add:&lt;br&gt;
Name detection&lt;br&gt;
Duplicate contact merging&lt;br&gt;
Better international phone number support&lt;br&gt;
Contact grouping&lt;br&gt;
Copy-to-clipboard improvements&lt;br&gt;
I'd love to hear your feedback and ideas.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;👉 Try Contact Grabber:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://www.smarteyeapps.com/contact-grabber" rel="noopener noreferrer"&gt;https://www.smarteyeapps.com/contact-grabber&lt;/a&gt;&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1y83swi6y8wlaztvct0i.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%2F1y83swi6y8wlaztvct0i.png" alt=" " width="800" height="512"&gt;&lt;/a&gt;&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fokgoy0m55rgifskr0dz0.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%2Fokgoy0m55rgifskr0dz0.png" alt=" " width="631" height="628"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
