<?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: Nabeel Krissane</title>
    <description>The latest articles on DEV Community by Nabeel Krissane (@nabilkrs).</description>
    <link>https://dev.to/nabilkrs</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%2F1044122%2Ff2a62f66-8ed8-4dec-a89b-b89265b54dfb.jpeg</url>
      <title>DEV Community: Nabeel Krissane</title>
      <link>https://dev.to/nabilkrs</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nabilkrs"/>
    <language>en</language>
    <item>
      <title>Stop Asking Cursor to “Build This”, Use These Prompts Instead</title>
      <dc:creator>Nabeel Krissane</dc:creator>
      <pubDate>Tue, 08 Sep 2026 08:00:00 +0000</pubDate>
      <link>https://dev.to/nabilkrs/stop-asking-cursor-to-build-this-use-these-prompts-instead-1n9h</link>
      <guid>https://dev.to/nabilkrs/stop-asking-cursor-to-build-this-use-these-prompts-instead-1n9h</guid>
      <description>&lt;p&gt;If you've ever typed &lt;strong&gt;"build this feature"&lt;/strong&gt; into Cursor and gotten back a half-working mess, you're not alone. Most developers use AI coding assistants the same way they'd talk to a junior intern with no context — vague instructions, no constraints, no examples.&lt;/p&gt;

&lt;p&gt;The result? Broken imports, inconsistent architecture, and code you end up rewriting anyway.&lt;/p&gt;

&lt;p&gt;In this guide, you'll learn &lt;strong&gt;exactly how to prompt Cursor AI&lt;/strong&gt; to generate production-ready code — not just "something that runs." We'll cover the core problem with vague prompting, a repeatable prompting framework, and real Flutter and Laravel code examples you can copy today.&lt;/p&gt;

&lt;p&gt;By the end, you'll know how to turn Cursor from a guessing machine into a reliable coding partner.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem: Why "Build This" Prompts Fail
&lt;/h2&gt;

&lt;p&gt;When you type something like:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Build a login screen"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Cursor has almost no context. It doesn't know:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your project's folder structure&lt;/li&gt;
&lt;li&gt;Your state management approach (Provider? Riverpod? Bloc?)&lt;/li&gt;
&lt;li&gt;Your naming conventions&lt;/li&gt;
&lt;li&gt;Whether you use a service layer or call APIs directly in widgets&lt;/li&gt;
&lt;li&gt;Your error-handling pattern&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So it fills in the blanks with &lt;strong&gt;generic assumptions&lt;/strong&gt; — often based on outdated tutorials or mismatched patterns. That's why the output feels "almost right" but never quite fits your codebase.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Developers Keep Doing This
&lt;/h3&gt;

&lt;p&gt;It's not laziness — it's a habit carried over from Google searches and Stack Overflow, where short, vague queries usually work fine. But AI code generation isn't search. It's &lt;strong&gt;instruction-following&lt;/strong&gt;, and instructions need structure to be useful.&lt;/p&gt;

&lt;p&gt;The common mistakes look like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Asking for a whole feature in one prompt instead of breaking it into steps&lt;/li&gt;
&lt;li&gt;Not specifying architecture, packages, or naming conventions&lt;/li&gt;
&lt;li&gt;Not giving Cursor an example of existing code style&lt;/li&gt;
&lt;li&gt;Never asking Cursor to explain its reasoning before generating code&lt;/li&gt;
&lt;li&gt;Accepting the first output without reviewing or iterating&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The Solution: A Prompting Framework, Not a Prompt
&lt;/h2&gt;

&lt;p&gt;Instead of one big vague request, treat Cursor like a &lt;strong&gt;pair programmer who needs a brief&lt;/strong&gt;. Give it:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Context&lt;/strong&gt; — what the project is, what stack you use&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Constraints&lt;/strong&gt; — architecture, naming, folder structure&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scope&lt;/strong&gt; — one small task at a time, not a whole feature&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Example&lt;/strong&gt; — a snippet of existing code style, if possible&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Output format&lt;/strong&gt; — ask for explanations, not just code&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This turns Cursor from a "guesser" into a "follower of your standards."&lt;/p&gt;




&lt;h2&gt;
  
  
  Step-by-Step Implementation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: Setup — Give Cursor Project Context First
&lt;/h3&gt;

&lt;p&gt;Before asking for any code, prime Cursor with a system-level prompt. In Cursor, you can do this in a &lt;code&gt;.cursorrules&lt;/code&gt; file at your project root, or as the first message in a new chat.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# .cursorrules&lt;/span&gt;

This is a Flutter project using:
&lt;span class="p"&gt;-&lt;/span&gt; Clean Architecture (data / domain / presentation layers)
&lt;span class="p"&gt;-&lt;/span&gt; Riverpod for state management
&lt;span class="p"&gt;-&lt;/span&gt; Dio for networking
&lt;span class="p"&gt;-&lt;/span&gt; Freezed for models

Rules:
&lt;span class="p"&gt;-&lt;/span&gt; Always place API calls inside a repository class, never inside widgets
&lt;span class="p"&gt;-&lt;/span&gt; Use snake_case for file names, PascalCase for class names
&lt;span class="p"&gt;-&lt;/span&gt; Always return a Result&lt;span class="nt"&gt;&amp;lt;T&amp;gt;&lt;/span&gt; type instead of throwing raw exceptions
&lt;span class="p"&gt;-&lt;/span&gt; Prefer StatelessWidget + Riverpod over StatefulWidget
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This single file changes everything. Now every prompt you write is interpreted &lt;strong&gt;inside your project's rules&lt;/strong&gt;, not generic defaults.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Configuration — Scope the Task Narrowly
&lt;/h3&gt;

&lt;p&gt;Instead of:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Build user authentication"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Break it down:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Create a &lt;code&gt;AuthRepository&lt;/code&gt; class that handles login via POST &lt;code&gt;/api/login&lt;/code&gt;, following the existing repository pattern in &lt;code&gt;lib/data/repositories/user_repository.dart&lt;/code&gt;. Return a &lt;code&gt;Result&amp;lt;User&amp;gt;&lt;/code&gt; type."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Narrow scope = fewer wrong assumptions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Core Implementation — The Actual Prompt Template
&lt;/h3&gt;

&lt;p&gt;Here's a reusable prompt template for feature work:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Context: [what this feature does and where it fits]
Constraints: [architecture, packages, patterns to follow]
Task: [the single, specific thing to build]
Reference: [existing file/class to match style with]
Output: Generate the code, then explain any assumptions you made.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Real example — Flutter login repository:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Context: I need a login feature for a Flutter app using Clean Architecture.
Constraints: Use Dio for networking, Riverpod for state, return Result&amp;lt;T&amp;gt; instead of throwing.
Task: Create an AuthRepository with a login(email, password) method.
Reference: Follow the pattern in lib/data/repositories/user_repository.dart
Output: Generate the code, then explain any assumptions you made.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cursor's output (cleaned up):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="c1"&gt;// lib/data/repositories/auth_repository.dart&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AuthRepository&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;Dio&lt;/span&gt; &lt;span class="n"&gt;_dio&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="n"&gt;AuthRepository&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;_dio&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&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="n"&gt;_dio&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'/api/login'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;data:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s"&gt;'email'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;'password'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;

      &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromJson&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'user'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;success&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="kd"&gt;on&lt;/span&gt; &lt;span class="n"&gt;DioException&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;failure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;message&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="s"&gt;'Login failed'&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;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice the difference: it follows a repository pattern, uses a &lt;code&gt;Result&amp;lt;T&amp;gt;&lt;/code&gt; wrapper, and matches your existing conventions — because you told it to.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real example — Laravel API endpoint:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Context: Laravel 11 API using Sanctum for auth, following Repository + Service pattern.
Constraints: Controllers should stay thin; business logic goes in Service classes.
Task: Create a login endpoint that returns a token on success.
Reference: Follow the structure in app/Services/UserService.php
Output: Generate the code, then explain any assumptions you made.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="c1"&gt;// app/Services/AuthService.php&lt;/span&gt;

&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;App\Services&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;App\Models\User&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Support\Facades\Hash&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Validation\ValidationException&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AuthService&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$credentials&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;array&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'email'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$credentials&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'email'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nv"&gt;$user&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nc"&gt;Hash&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$credentials&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'password'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nc"&gt;ValidationException&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;withMessages&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
                &lt;span class="s1"&gt;'email'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'Invalid credentials.'&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;span class="nv"&gt;$token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;createToken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'api-token'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;plainTextToken&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="s1"&gt;'user'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'token'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$token&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;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="c1"&gt;// app/Http/Controllers/AuthController.php&lt;/span&gt;

&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;App\Http\Controllers&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;App\Services\AuthService&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Http\Request&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AuthController&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Controller&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;AuthService&lt;/span&gt; &lt;span class="nv"&gt;$authService&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Request&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$validated&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
            &lt;span class="s1"&gt;'email'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'required|email'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'password'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'required|string'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;]);&lt;/span&gt;

        &lt;span class="nv"&gt;$result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;authService&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$validated&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;response&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$result&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;The controller stays thin, the logic lives in a service — because the prompt told Cursor to respect that separation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Final Integration — Ask for a Review Pass
&lt;/h3&gt;

&lt;p&gt;After Cursor generates code, don't stop there. Run a follow-up prompt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Review the code you just generated. Check for:
- Error handling gaps
- Naming consistency with the rest of the project
- Any hardcoded values that should be constants or env variables
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This second pass catches issues Cursor's first draft usually misses.&lt;/p&gt;




&lt;h2&gt;
  
  
  Common Mistakes Developers Make with Cursor
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Asking for entire features in one prompt&lt;/strong&gt;&lt;br&gt;
This overwhelms context and produces inconsistent files. Break features into 3–5 smaller prompts instead.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Never providing a style reference&lt;/strong&gt;&lt;br&gt;
Without an example file, Cursor defaults to generic patterns that don't match your codebase.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Skipping the &lt;code&gt;.cursorrules&lt;/code&gt; file&lt;/strong&gt;&lt;br&gt;
This is the single most underused feature. It's the difference between re-explaining your stack every time and having Cursor "just know" it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Accepting output without reviewing&lt;/strong&gt;&lt;br&gt;
AI-generated code can look correct while quietly missing edge cases like null checks or expired tokens.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Not specifying the output format&lt;/strong&gt;&lt;br&gt;
If you don't ask for explanations, Cursor gives you code with zero reasoning — making it harder to trust or debug later.&lt;/p&gt;




&lt;h2&gt;
  
  
  Best Practices for Prompting Cursor
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;One task per prompt.&lt;/strong&gt; Small, scoped requests produce more reliable code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keep a living &lt;code&gt;.cursorrules&lt;/code&gt; file.&lt;/strong&gt; Update it as your architecture evolves.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Always reference an existing file.&lt;/strong&gt; This anchors style and structure.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ask "why" before "what."&lt;/strong&gt; Prompt Cursor to explain its approach before generating code for complex logic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use Result/Either types instead of raw exceptions&lt;/strong&gt; in both Flutter and Laravel — it keeps error handling predictable and easy for AI to replicate consistently.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Version your prompts.&lt;/strong&gt; Save your best prompt templates in a &lt;code&gt;/prompts&lt;/code&gt; folder in your repo so your team reuses them.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Visual Explanation (What to Include Here)
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Here you should show a side-by-side screenshot: a vague "build this" prompt output on the left, vs. a structured prompt output on the right, highlighting the architecture differences.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Here you should show the &lt;code&gt;.cursorrules&lt;/code&gt; file open in Cursor's file explorer, with the project folder structure visible in the sidebar.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Here you should show a diagram of the prompting flow: Context → Constraints → Scope → Reference → Output, as a simple horizontal flowchart.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Real-World Use Case
&lt;/h2&gt;

&lt;p&gt;This prompting approach isn't just for solo side projects — it's exactly how teams shipping production software use AI tools:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SaaS apps&lt;/strong&gt;: Teams use &lt;code&gt;.cursorrules&lt;/code&gt; to enforce consistent service/repository patterns across dozens of contributors.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mobile apps&lt;/strong&gt;: Flutter teams use scoped prompts to generate feature modules that match Clean Architecture without manual boilerplate.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Admin dashboards&lt;/strong&gt;: Laravel teams use structured prompts to keep controllers thin and logic testable, even when AI writes most of the first draft.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Production systems&lt;/strong&gt;: Companies increasingly review AI-generated PRs the same way they review human ones — which only works if the AI output already follows house style.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The difference between frustrating AI output and genuinely useful code isn't the model — it's the prompt.&lt;/p&gt;

&lt;p&gt;Stop typing "build this" and expecting Cursor to read your mind. Give it context, constraints, scope, and a reference file. Ask it to explain its reasoning. Review its output like you would a junior developer's PR.&lt;/p&gt;

&lt;p&gt;Do this consistently, and Cursor stops being a slot machine and starts being an actual extension of your team.&lt;/p&gt;




&lt;h2&gt;
  
  
  Want to Build React Apps Faster with AI?
&lt;/h2&gt;

&lt;p&gt;Learning React is one thing. Building real-world applications efficiently is another.&lt;/p&gt;

&lt;p&gt;You can use ChatGPT, Claude, and Cursor to write code, debug issues, refactor components, generate features, and speed up your development but getting useful results depends heavily on &lt;strong&gt;how you prompt AI&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That’s why I created &lt;strong&gt;&lt;a href="https://cimoradevtools.gumroad.com/l/ultimate-react-cursor-prompt-library" rel="noopener noreferrer"&gt;The Ultimate React + Cursor Prompt Library (1000+ AI Prompts)&lt;/a&gt;&lt;/strong&gt; a practical collection of AI prompts designed specifically for React developers.&lt;/p&gt;

&lt;p&gt;Inside the library, you’ll find &lt;strong&gt;1,000+ practical prompts&lt;/strong&gt; covering React development, UI components, debugging, refactoring, performance optimization, API integration, state management, testing, architecture, and more.&lt;/p&gt;

&lt;p&gt;Each prompt is designed to help you get better results from AI coding assistants like &lt;strong&gt;Cursor, ChatGPT, and Claude&lt;/strong&gt;, so you can spend less time figuring out what to ask and more time building.&lt;/p&gt;

&lt;p&gt;Instead of staring at a blank Cursor chat wondering what prompt to write, you can start with proven prompts and adapt them to your own projects.&lt;/p&gt;

&lt;p&gt;Whether you’re building a SaaS, freelance project, startup, dashboard, or personal application, this library can help you &lt;strong&gt;code faster, solve problems quicker, and get more out of AI-assisted development.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://cimoradevtools.gumroad.com/l/ultimate-react-cursor-prompt-library" rel="noopener noreferrer"&gt;The Ultimate React + Cursor Prompt Library: 1000+ AI Prompts →&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>react</category>
      <category>cursor</category>
      <category>promptengineering</category>
    </item>
    <item>
      <title>15 Cursor Prompts Every React Developer Should Have Saved</title>
      <dc:creator>Nabeel Krissane</dc:creator>
      <pubDate>Sat, 05 Sep 2026 08:00:00 +0000</pubDate>
      <link>https://dev.to/nabilkrs/15-cursor-prompts-every-react-developer-should-have-saved-1nph</link>
      <guid>https://dev.to/nabilkrs/15-cursor-prompts-every-react-developer-should-have-saved-1nph</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;You open Cursor, type a vague request, and get back code that half-works, ignores your project structure, or hallucinates a hook that doesn't exist.&lt;/p&gt;

&lt;p&gt;Every React developer using AI-assisted coding tools has hit this wall. The problem usually isn't Cursor — it's the prompt.&lt;/p&gt;

&lt;p&gt;A well-structured Cursor prompt can turn a 20-minute refactor into a 30-second task. A lazy one wastes your time debugging AI-generated bugs.&lt;/p&gt;

&lt;p&gt;In this article, you'll get 15 battle-tested Cursor prompts for React development — for components, hooks, performance, testing, and debugging — that you can copy, save, and reuse in every project.&lt;/p&gt;

&lt;p&gt;By the end, you'll have a personal "prompt library" that makes Cursor feel like a senior React engineer sitting next to you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Most Cursor Prompts Fail for React Projects
&lt;/h2&gt;

&lt;p&gt;Most developers treat Cursor like a search engine. They type short, generic requests such as "make a login form" or "fix this bug."&lt;/p&gt;

&lt;p&gt;The AI has no context about your component structure, state management approach, or styling system, so it guesses — and guesses are where bugs come from.&lt;/p&gt;

&lt;p&gt;Three common mistakes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No context&lt;/strong&gt;: not mentioning React version, TypeScript, or state library&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No constraints&lt;/strong&gt;: not specifying performance, accessibility, or file structure rules&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No examples&lt;/strong&gt;: not showing existing code patterns the AI should follow&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Fixing this isn't about learning "AI magic." It's about writing prompts the way you'd brief a new teammate.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Solution: Structured, Reusable Prompts
&lt;/h2&gt;

&lt;p&gt;Good Cursor prompts follow a simple formula:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Context + Task + Constraints + Output format&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead of "create a modal component," you say what framework, styling approach, accessibility needs, and file structure to use.&lt;/p&gt;

&lt;p&gt;Below are 15 prompts organized by category. Save them in a notes app, a &lt;code&gt;.cursorrules&lt;/code&gt; file, or a personal snippet manager.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 1: Setup — Preparing Cursor for React Work
&lt;/h2&gt;

&lt;p&gt;Before using any prompt, give Cursor project-level context. Create a &lt;code&gt;.cursorrules&lt;/code&gt; file in your project root:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;This is a React 18 + TypeScript project using:
- Vite as the bundler
- Tailwind CSS for styling
- React Query for server state
- Zustand for client state
- React Router v6

Follow these rules:
- Use functional components only
- Prefer named exports
- Always type props with interfaces
- Keep components under 150 lines
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This single file dramatically improves every prompt result because Cursor now understands your stack before you ask anything.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Configuration — Component Generation Prompts
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Prompt 1 — Generate a typed functional component&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Create a React functional component called `UserCard` using TypeScript.
Props: name (string), email (string), avatarUrl (string, optional).
Use Tailwind CSS for styling.
Export as a named export.
Include a JSDoc comment above the component.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Prompt 2 — Convert class component to functional&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Convert this class component into a functional component using hooks.
Preserve all lifecycle behavior using useEffect.
Keep the same prop types.
Here is the class component: [paste code]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Prompt 3 — Generate a reusable form component&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Create a reusable `Input` component with TypeScript that supports:
- label, error message, and helper text props
- forwardRef for form libraries like react-hook-form
- Tailwind styling with an error state (red border)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 3: Core Implementation — Hooks, State, and Logic Prompts
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Prompt 4 — Custom hook generation&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Create a custom hook called `useDebounce` that:
- Accepts a value and delay (ms)
- Returns the debounced value
- Uses TypeScript generics so it works with any type
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example output you should expect:&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="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="nx"&gt;useEffect&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="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;useDebounce&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;delay&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;debouncedValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setDebouncedValue&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="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nf"&gt;useEffect&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;timer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setDebouncedValue&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;delay&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;clearTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;timer&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;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;debouncedValue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;useDebounce&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Prompt 5 — Fetch data with React Query&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Write a React Query hook called `useUsers` that:
- Fetches from GET /api/users
- Uses axios
- Has a 5-minute stale time
- Returns data, isLoading, and error
Follow React Query v5 syntax.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Prompt 6 — Global state with Zustand&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Create a Zustand store called `useCartStore` with:
- items array
- addItem, removeItem, clearCart actions
- a computed total price
Type everything with TypeScript.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Prompt 7 — Form validation logic&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Create form validation logic for a signup form using react-hook-form and zod.
Fields: email, password (min 8 chars), confirmPassword (must match password).
Return the schema and a usage example.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 4: Final Integration — Debugging, Testing, and Refactor Prompts
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Prompt 8 — Explain and fix a bug&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Here is a React component throwing "Cannot update state on unmounted component".
Explain why this happens and fix it using proper cleanup.
Code: [paste code]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Prompt 9 — Optimize re-renders&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Review this component for unnecessary re-renders.
Suggest fixes using React.memo, useCallback, or useMemo where appropriate.
Explain each change briefly.
Code: [paste code]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Prompt 10 — Refactor prop drilling&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;This component passes props through 4 levels of children.
Refactor it using React Context to avoid prop drilling.
Keep the component API the same for the parent.
Code: [paste code]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Prompt 11 — Write unit tests&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Write unit tests for this component using React Testing Library and Vitest.
Cover: default render, click interactions, and conditional rendering.
Do not test implementation details.
Code: [paste code]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Prompt 12 — Accessibility audit&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Review this component for accessibility issues.
Check ARIA attributes, keyboard navigation, and color contrast assumptions.
List each issue and provide the fixed code.
Code: [paste code]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Prompt 13 — Convert to Suspense-based data fetching&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Refactor this useEffect-based data fetching into a Suspense-compatible pattern using React Query's useSuspenseQuery.
Include the required Suspense boundary and fallback UI.
Code: [paste code]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Prompt 14 — Generate a loading/error/empty state pattern&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Create a reusable `&amp;lt;AsyncBoundary&amp;gt;` component that handles loading, error, and empty states for any children.
Accept isLoading, error, and isEmpty as props.
Keep it generic and reusable across the app.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Prompt 15 — Explain code like a senior engineer&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Explain this React code as if teaching a mid-level developer.
Focus on why it's written this way, not just what it does.
Point out any anti-patterns.
Code: [paste code]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Common Mistakes Developers Make With Cursor Prompts
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Pasting code without context&lt;/strong&gt;&lt;br&gt;
Cursor guesses your stack. Always mention React version, TypeScript, and libraries.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Asking for "the whole app" in one prompt&lt;/strong&gt;&lt;br&gt;
Large, vague prompts produce inconsistent code. Break tasks into components, hooks, and logic separately.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Not specifying output format&lt;/strong&gt;&lt;br&gt;
Without asking for TypeScript, tests, or comments, Cursor defaults to the simplest possible output.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Blindly accepting generated code&lt;/strong&gt;&lt;br&gt;
AI-generated code can look correct but miss edge cases. Always review before merging.&lt;/p&gt;

&lt;h2&gt;
  
  
  Best Practices for Using Cursor in React Projects
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Keep a &lt;code&gt;.cursorrules&lt;/code&gt; file updated as your stack evolves&lt;/li&gt;
&lt;li&gt;Save your best prompts in a shared team doc — consistency matters more than cleverness&lt;/li&gt;
&lt;li&gt;Ask Cursor to explain, not just generate — this catches bad assumptions early&lt;/li&gt;
&lt;li&gt;Use small, single-responsibility prompts instead of one giant request&lt;/li&gt;
&lt;li&gt;Always request TypeScript types explicitly if your project uses them&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Visual Explanation Section
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;(For your published article, add these visuals)&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Screenshot&lt;/strong&gt;: &lt;code&gt;.cursorrules&lt;/code&gt; file open in Cursor's editor, showing the project context block&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Screenshot&lt;/strong&gt;: Before/after code diff showing a &lt;code&gt;useEffect&lt;/code&gt; cleanup fix from Prompt 8&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Diagram&lt;/strong&gt;: A simple flow showing "Prompt → Cursor → Generated Code → Developer Review → Merge"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Screenshot&lt;/strong&gt;: React Testing Library test output in the terminal after using Prompt 11&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Real-World Use Case
&lt;/h2&gt;

&lt;p&gt;These prompts aren't theoretical — they map directly to daily work on production React apps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SaaS dashboards&lt;/strong&gt;: Prompt 6 (Zustand store) and Prompt 5 (React Query) are used constantly for billing, user, and subscription state.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Admin panels&lt;/strong&gt;: Prompt 3 (reusable form inputs) and Prompt 7 (validation) speed up CRUD screen development.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mobile-first React apps&lt;/strong&gt;: Prompt 12 (accessibility audit) matters heavily for apps targeting wide user bases.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Large production codebases&lt;/strong&gt;: Prompt 10 (prop drilling refactor) and Prompt 9 (re-render optimization) are used during scaling and performance passes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Cursor is only as good as the prompts you give it. Generic requests produce generic, often broken code. Structured prompts — with context, constraints, and clear output expectations — produce code that actually fits your project.&lt;/p&gt;

&lt;p&gt;The 15 prompts above cover the real day-to-day work of a React developer: components, hooks, state, testing, debugging, and refactoring.&lt;/p&gt;

&lt;p&gt;Save them, adapt them to your stack, and build your own library over time. That library becomes one of the highest-leverage tools in your workflow.&lt;/p&gt;




&lt;h3&gt;
  
  
  Want to Build React Apps Faster with AI?
&lt;/h3&gt;

&lt;p&gt;Learning React is one thing. Building real-world applications efficiently is another.&lt;/p&gt;

&lt;p&gt;You can use ChatGPT, Claude, and Cursor to write code, debug issues, refactor components, generate features, and speed up your development but getting useful results depends heavily on &lt;strong&gt;how you prompt AI&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That’s why I created &lt;strong&gt;&lt;a href="https://cimoradevtools.gumroad.com/l/ultimate-react-cursor-prompt-library" rel="noopener noreferrer"&gt;The Ultimate React + Cursor Prompt Library (1000+ AI Prompts)&lt;/a&gt;&lt;/strong&gt; a practical collection of AI prompts designed specifically for React developers.&lt;/p&gt;

&lt;p&gt;Inside the library, you’ll find &lt;strong&gt;1,000+ practical prompts&lt;/strong&gt; covering React development, UI components, debugging, refactoring, performance optimization, API integration, state management, testing, architecture, and more.&lt;/p&gt;

&lt;p&gt;Each prompt is designed to help you get better results from AI coding assistants like &lt;strong&gt;Cursor, ChatGPT, and Claude&lt;/strong&gt;, so you can spend less time figuring out what to ask and more time building.&lt;/p&gt;

&lt;p&gt;Instead of staring at a blank Cursor chat wondering what prompt to write, you can start with proven prompts and adapt them to your own projects.&lt;/p&gt;

&lt;p&gt;Whether you’re building a SaaS, freelance project, startup, dashboard, or personal application, this library can help you &lt;strong&gt;code faster, solve problems quicker, and get more out of AI-assisted development.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://cimoradevtools.gumroad.com/l/ultimate-react-cursor-prompt-library" rel="noopener noreferrer"&gt;The Ultimate React + Cursor Prompt Library: 1000+ AI Prompts →&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>cursor</category>
      <category>react</category>
      <category>ai</category>
      <category>promptengineering</category>
    </item>
    <item>
      <title>I Used Cursor AI to Build React Apps for 30 Days Here's What Actually Made Me Faster</title>
      <dc:creator>Nabeel Krissane</dc:creator>
      <pubDate>Fri, 04 Sep 2026 05:55:38 +0000</pubDate>
      <link>https://dev.to/nabilkrs/i-used-cursor-ai-to-build-react-apps-for-30-days-heres-what-actually-made-me-faster-4ek3</link>
      <guid>https://dev.to/nabilkrs/i-used-cursor-ai-to-build-react-apps-for-30-days-heres-what-actually-made-me-faster-4ek3</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Every developer has felt this pain: you know exactly what component you need to build, but you still spend 20 minutes typing boilerplate, fixing imports, and Googling syntax you've written a hundred times before.&lt;/p&gt;

&lt;p&gt;I spent 30 days using &lt;strong&gt;Cursor&lt;/strong&gt;, the AI-powered code editor, to build multiple React apps from scratch a dashboard, a SaaS landing page, and an internal admin tool. My goal was simple: figure out if Cursor actually makes React development faster, or if it's just another overhyped AI coding tool.&lt;/p&gt;

&lt;p&gt;In this article, you'll learn exactly what worked, what didn't, and the specific Cursor workflows that cut my React development time by roughly 40%. No hype just real code, real mistakes, and real results.&lt;/p&gt;

&lt;p&gt;If you're a React developer wondering whether Cursor is worth adopting into your workflow, this guide will save you the 30 days I spent testing it.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem: Why React Development Feels Slower Than It Should
&lt;/h2&gt;

&lt;p&gt;React itself isn't slow. The &lt;em&gt;process&lt;/em&gt; around it is.&lt;/p&gt;

&lt;p&gt;Most of the time developers lose isn't spent solving hard logic problems it's spent on repetitive, low-value work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Writing the same component boilerplate over and over&lt;/li&gt;
&lt;li&gt;Setting up props, types, and interfaces manually&lt;/li&gt;
&lt;li&gt;Switching between docs, Stack Overflow, and the editor&lt;/li&gt;
&lt;li&gt;Debugging small syntax or type errors&lt;/li&gt;
&lt;li&gt;Writing repetitive API integration code&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The usual "fix" developers reach for is copy-pasting old components and hacking them into shape. This works short-term, but it quietly creates messy, inconsistent codebases.&lt;/p&gt;

&lt;p&gt;Autocomplete tools like GitHub Copilot help a little, but they mostly guess line-by-line. They don't understand your entire project structure or your intent  which is exactly the gap Cursor tries to close.&lt;/p&gt;




&lt;h2&gt;
  
  
  Solution Overview: How Cursor Actually Helps
&lt;/h2&gt;

&lt;p&gt;Cursor isn't just "autocomplete with AI." It's a full editor built around AI-assisted coding, with three features that mattered most during my 30-day test:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Codebase-aware chat&lt;/strong&gt;  it reads your project context, not just the open file&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Inline edit (Cmd+K)&lt;/strong&gt;  you select code and describe changes in plain English&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-file generation&lt;/strong&gt;  it can scaffold components, hooks, and API logic together&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The real speed gain doesn't come from Cursor "writing your app for you." It comes from removing the repetitive typing and context-switching that slows React developers down.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step-by-Step: How I Used Cursor to Build React Apps Faster
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: Setup
&lt;/h3&gt;

&lt;p&gt;I started every project the same way  a standard Vite + React + TypeScript setup, since this is the most common stack developers use in 2025.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm create vite@latest my-app &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nt"&gt;--template&lt;/span&gt; react-ts
&lt;span class="nb"&gt;cd &lt;/span&gt;my-app
npm &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once inside Cursor, I opened the project folder directly. Cursor automatically indexes the codebase, which is what allows its chat and inline edits to understand your file structure, types, and existing components.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Installation / Configuration
&lt;/h3&gt;

&lt;p&gt;For consistent AI output, configuration matters more than people expect. I added a &lt;code&gt;.cursor/rules&lt;/code&gt; file to guide Cursor's suggestions toward my project's conventions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# .cursor/rules&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Use functional components with TypeScript
&lt;span class="p"&gt;-&lt;/span&gt; Use Tailwind CSS for styling
&lt;span class="p"&gt;-&lt;/span&gt; Prefer named exports over default exports
&lt;span class="p"&gt;-&lt;/span&gt; Keep components under 150 lines; extract logic into hooks
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This single step reduced the amount of "cleanup editing" I had to do after every AI-generated component by a noticeable margin.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Core Implementation
&lt;/h3&gt;

&lt;p&gt;This is where Cursor actually saved time. Instead of manually writing a data-fetching component, I selected a blank file, opened inline edit (Cmd+K), and described what I needed.&lt;/p&gt;

&lt;p&gt;Here's a real example  a reusable hook for fetching user data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// hooks/useUsers.ts&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;useState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useEffect&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="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&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;useUsers&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;users&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setUsers&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;User&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="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setLoading&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="kc"&gt;true&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;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setError&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nf"&gt;useEffect&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fetchUsers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &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="k"&gt;try&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="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/api/users&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Failed to fetch users&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="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;[]&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;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nf"&gt;setUsers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;setError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Unknown error&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;setLoading&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&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;span class="nf"&gt;fetchUsers&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;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&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;Cursor generated this in seconds, correctly typed, following the conventions I'd defined in my rules file. My job shifted from &lt;em&gt;typing&lt;/em&gt; to &lt;em&gt;reviewing&lt;/em&gt;  which is a faster and less error-prone way to work.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Final Integration
&lt;/h3&gt;

&lt;p&gt;The last step was wiring the hook into a component:&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="c1"&gt;// components/UserList.tsx&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;useUsers&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="s2"&gt;../hooks/useUsers&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;UserList&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;users&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useUsers&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;loading&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;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Loading users...&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&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;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-red-500"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Error: &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;error&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;p&lt;/span&gt;&lt;span class="p"&gt;&amp;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;ul&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"divide-y divide-gray-200"&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;users&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;user&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;li&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;user&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="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"py-2"&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;p&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"font-medium"&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;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&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;p&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;p&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-sm text-gray-500"&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;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&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;p&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;li&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;ul&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;p&gt;Because Cursor had already seen the &lt;code&gt;useUsers&lt;/code&gt; hook during generation, the component's types and imports matched perfectly  no manual fixing required.&lt;/p&gt;




&lt;h2&gt;
  
  
  Common Mistakes Developers Make With AI Coding Tools
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Blindly accepting generated code&lt;/strong&gt;&lt;br&gt;
AI tools like Cursor are confident even when wrong. Always read the logic before accepting  especially around state management and API error handling.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Not giving project context&lt;/strong&gt;&lt;br&gt;
Without a rules file or clear prompts, Cursor defaults to generic patterns that don't match your codebase style.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Using AI for architecture decisions&lt;/strong&gt;&lt;br&gt;
Cursor is great at implementation, not judgment. Decisions like state management strategy or folder structure should still come from you.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Prompting too vaguely&lt;/strong&gt;&lt;br&gt;
"Build a login form" gives generic results. "Build a login form using React Hook Form, Zod validation, and Tailwind, matching the existing Button component" gives production-ready results.&lt;/p&gt;




&lt;h2&gt;
  
  
  Best Practices for Using Cursor With React
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Write a &lt;code&gt;.cursor/rules&lt;/code&gt; file early&lt;/strong&gt;  it's the single biggest lever for consistent output&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keep prompts specific&lt;/strong&gt;  mention libraries, styling approach, and existing components&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use inline edit for small changes&lt;/strong&gt;, and chat for multi-file features&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Review generated code like a PR&lt;/strong&gt;, not like magic&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Break large features into smaller prompts&lt;/strong&gt;  this reduces hallucinated logic&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Combine AI generation with TypeScript strict mode&lt;/strong&gt; to catch mismatches early&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Visual Explanation (What to Show Here)
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;If publishing this on Medium, add these visuals for extra clarity:&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Screenshot of the Cursor editor with the inline edit (Cmd+K) prompt box open&lt;/li&gt;
&lt;li&gt;Screenshot of the &lt;code&gt;.cursor/rules&lt;/code&gt; file next to a generated component&lt;/li&gt;
&lt;li&gt;A before/after diagram showing manual coding time vs. Cursor-assisted coding time&lt;/li&gt;
&lt;li&gt;A folder structure screenshot showing &lt;code&gt;hooks/&lt;/code&gt;, &lt;code&gt;components/&lt;/code&gt;, and &lt;code&gt;.cursor/rules&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Real-World Use Cases
&lt;/h2&gt;

&lt;p&gt;This workflow isn't just for side projects. The same pattern applies to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SaaS dashboards&lt;/strong&gt;  repetitive CRUD components and data tables&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Admin panels&lt;/strong&gt;  forms, filters, and table views with similar structure&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mobile-responsive marketing sites&lt;/strong&gt;  fast section-by-section scaffolding&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Internal tools&lt;/strong&gt;  quick prototypes that still need clean, typed code&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Any codebase with repeated component patterns is where Cursor saves the most time  because the AI has consistent context to learn from.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;After 30 days of building React apps with Cursor, the biggest lesson wasn't that "AI writes better code than developers." It doesn't.&lt;/p&gt;

&lt;p&gt;The real win is that Cursor removes repetitive, low-value work  boilerplate, typing, context-switching  so you spend more time on actual engineering decisions.&lt;/p&gt;

&lt;p&gt;The developers who benefit most from Cursor aren't the ones who blindly accept every suggestion. They're the ones who set clear conventions, write specific prompts, and review AI output like any other code.&lt;/p&gt;

&lt;p&gt;If you're serious about speeding up your React workflow, the setup matters as much as the tool itself.&lt;/p&gt;




&lt;h3&gt;
  
  
  Want to Build React Apps Faster with AI?
&lt;/h3&gt;

&lt;p&gt;Learning React is one thing. Building real-world applications efficiently is another.&lt;/p&gt;

&lt;p&gt;You can use ChatGPT, Claude, and Cursor to write code, debug issues, refactor components, generate features, and speed up your development but getting useful results depends heavily on &lt;strong&gt;how you prompt AI&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That’s why I created &lt;strong&gt;&lt;a href="https://cimoradevtools.gumroad.com/l/ultimate-react-cursor-prompt-library" rel="noopener noreferrer"&gt;The Ultimate React + Cursor Prompt Library (1000+ AI Prompts)&lt;/a&gt;&lt;/strong&gt; a practical collection of AI prompts designed specifically for React developers.&lt;/p&gt;

&lt;p&gt;Inside the library, you’ll find &lt;strong&gt;1,000+ practical prompts&lt;/strong&gt; covering React development, UI components, debugging, refactoring, performance optimization, API integration, state management, testing, architecture, and more.&lt;/p&gt;

&lt;p&gt;Each prompt is designed to help you get better results from AI coding assistants like &lt;strong&gt;Cursor, ChatGPT, and Claude&lt;/strong&gt;, so you can spend less time figuring out what to ask and more time building.&lt;/p&gt;

&lt;p&gt;Instead of staring at a blank Cursor chat wondering what prompt to write, you can start with proven prompts and adapt them to your own projects.&lt;/p&gt;

&lt;p&gt;Whether you’re building a SaaS, freelance project, startup, dashboard, or personal application, this library can help you &lt;strong&gt;code faster, solve problems quicker, and get more out of AI-assisted development.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://cimoradevtools.gumroad.com/l/ultimate-react-cursor-prompt-library" rel="noopener noreferrer"&gt;The Ultimate React + Cursor Prompt Library: 1000+ AI Prompts →&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>cursor</category>
      <category>claude</category>
      <category>promptengineering</category>
    </item>
    <item>
      <title>From Prompt to Product: 12 Flutter + AI Apps You Can Build</title>
      <dc:creator>Nabeel Krissane</dc:creator>
      <pubDate>Tue, 25 Aug 2026 08:00:00 +0000</pubDate>
      <link>https://dev.to/nabilkrs/from-prompt-to-product-12-flutter-ai-apps-you-can-build-2j0d</link>
      <guid>https://dev.to/nabilkrs/from-prompt-to-product-12-flutter-ai-apps-you-can-build-2j0d</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Most Flutter developers know how to build clean UIs — but struggle to turn a simple app idea into something powered by real AI features.&lt;/p&gt;

&lt;p&gt;You've probably seen dozens of "AI app" tutorials that stop at a single API call and never show you how to structure a real, production-ready Flutter + AI app.&lt;/p&gt;

&lt;p&gt;That's the real problem: there's a huge gap between "calling an API" and "building a product."&lt;/p&gt;

&lt;p&gt;In this article, you'll learn &lt;strong&gt;12 practical Flutter + AI app ideas&lt;/strong&gt; you can actually build, along with the architecture, code patterns, and implementation steps for each — so you go from prompt to product, not just prompt to demo.&lt;/p&gt;

&lt;p&gt;By the end, you'll have a clear roadmap for building real AI-powered Flutter apps using tools like OpenAI, Gemini, and on-device ML.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem: Why Most "Flutter + AI" Projects Never Ship
&lt;/h2&gt;

&lt;p&gt;Developers usually approach AI integration the wrong way. Here's what typically goes wrong:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;They call an AI API directly from the UI layer, with no separation of concerns.&lt;/li&gt;
&lt;li&gt;They hardcode API keys in the Flutter app (a serious security risk).&lt;/li&gt;
&lt;li&gt;They don't handle streaming responses, so the UI feels frozen.&lt;/li&gt;
&lt;li&gt;They skip error handling for rate limits, timeouts, and malformed responses.&lt;/li&gt;
&lt;li&gt;They never think about cost control — one runaway loop can burn your API budget.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is why so many "AI Flutter apps" stay stuck as weekend prototypes instead of becoming real products.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Solution: A Repeatable Architecture Pattern
&lt;/h2&gt;

&lt;p&gt;Every app below follows the same core architecture, so once you learn it, you can reuse it across all 12 ideas:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;UI Layer (Widgets)
   ↓
State Management (Riverpod / Bloc)
   ↓
Repository Layer (abstracts AI provider)
   ↓
API Service Layer (handles requests, keys, retries)
   ↓
Backend Proxy (Node.js / Laravel) — keeps API keys safe
   ↓
AI Provider (OpenAI, Gemini, Claude, etc.)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This pattern keeps your Flutter app clean, secure, and scalable — regardless of which AI provider you use.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step-by-Step Implementation (Base Setup Used in All 12 Apps)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: Project Setup
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;flutter create ai_flutter_app
&lt;span class="nb"&gt;cd &lt;/span&gt;ai_flutter_app
flutter pub add dio flutter_riverpod flutter_dotenv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Environment Configuration
&lt;/h3&gt;

&lt;p&gt;Never store API keys in your Flutter code. Use a &lt;code&gt;.env&lt;/code&gt; file loaded only on your &lt;strong&gt;backend&lt;/strong&gt;, not the client.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="c1"&gt;// lib/core/env.dart&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Env&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;backendUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromEnvironment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;'BACKEND_URL'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;defaultValue:&lt;/span&gt; &lt;span class="s"&gt;'https://your-backend.com/api'&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;Your Flutter app talks to your backend — your backend talks to the AI provider. This keeps your keys safe.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Core API Service
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="c1"&gt;// lib/core/services/ai_service.dart&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:dio/dio.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AIService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;Dio&lt;/span&gt; &lt;span class="n"&gt;_dio&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Dio&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseOptions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nl"&gt;baseUrl:&lt;/span&gt; &lt;span class="n"&gt;Env&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;backendUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;connectTimeout:&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Duration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;seconds:&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;));&lt;/span&gt;

  &lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;generateText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&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="n"&gt;_dio&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'/ai/generate'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;data:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s"&gt;'prompt'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'result'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="kd"&gt;on&lt;/span&gt; &lt;span class="n"&gt;DioException&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="n"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'AI request failed: &lt;/span&gt;&lt;span class="si"&gt;${e.message}&lt;/span&gt;&lt;span class="s"&gt;'&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;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4: State Management with Riverpod
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="c1"&gt;// lib/features/chat/chat_provider.dart&lt;/span&gt;
&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;aiServiceProvider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Provider&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;AIService&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;chatResponseProvider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;FutureProvider&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;family&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;((&lt;/span&gt;&lt;span class="n"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ref&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;aiServiceProvider&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;generateText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prompt&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;This same 4-step pattern is the foundation for every app idea below.&lt;/p&gt;




&lt;h2&gt;
  
  
  12 Flutter + AI App Ideas You Can Build
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. AI Chat Assistant App
&lt;/h3&gt;

&lt;p&gt;A ChatGPT-style app using streaming responses and conversation history stored locally with Hive or Isar.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. AI Resume Builder
&lt;/h3&gt;

&lt;p&gt;User inputs their experience → AI generates polished resume content → export as PDF using the &lt;code&gt;pdf&lt;/code&gt; package.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. AI Image Caption Generator
&lt;/h3&gt;

&lt;p&gt;Upload an image → send to a vision model → generate SEO-friendly captions for social media.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. AI Voice Journal App
&lt;/h3&gt;

&lt;p&gt;Record voice → transcribe with Whisper API → summarize entries using GPT for mood tracking.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. AI Recipe Generator
&lt;/h3&gt;

&lt;p&gt;User enters ingredients they have → AI suggests recipes → save favorites offline.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. AI Study Buddy / Flashcard Generator
&lt;/h3&gt;

&lt;p&gt;Paste notes → AI converts them into flashcards → spaced repetition logic built with local storage.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. AI Code Explainer App
&lt;/h3&gt;

&lt;p&gt;Paste a code snippet → AI explains it line by line — great for junior devs and students.&lt;/p&gt;

&lt;h3&gt;
  
  
  8. AI Fitness Plan Generator
&lt;/h3&gt;

&lt;p&gt;User inputs goals and equipment → AI generates a weekly workout plan with progress tracking.&lt;/p&gt;

&lt;h3&gt;
  
  
  9. AI Customer Support Chatbot (SaaS Widget)
&lt;/h3&gt;

&lt;p&gt;Embeddable Flutter Web widget that answers FAQs using a custom knowledge base + RAG.&lt;/p&gt;

&lt;h3&gt;
  
  
  10. AI Travel Itinerary Planner
&lt;/h3&gt;

&lt;p&gt;User enters destination and days → AI builds a day-by-day itinerary with local suggestions.&lt;/p&gt;

&lt;h3&gt;
  
  
  11. AI Email/Message Rewriter
&lt;/h3&gt;

&lt;p&gt;Paste rough text → AI rewrites it in different tones (professional, friendly, concise).&lt;/p&gt;

&lt;h3&gt;
  
  
  12. AI-Powered Admin Dashboard Insights
&lt;/h3&gt;

&lt;p&gt;Flutter Web dashboard where AI summarizes analytics data into plain-English insights for non-technical stakeholders.&lt;/p&gt;




&lt;h2&gt;
  
  
  Common Mistakes Developers Make
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Calling AI APIs directly from Flutter&lt;/strong&gt; — exposes your API key and lets anyone drain your quota.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No loading/streaming states&lt;/strong&gt; — makes the app feel broken during generation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ignoring token limits&lt;/strong&gt; — leads to truncated or failed responses on longer prompts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No caching&lt;/strong&gt; — repeated identical requests waste money and time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Skipping error boundaries&lt;/strong&gt; — a single failed API call crashes the whole flow instead of degrading gracefully.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Best Practices &amp;amp; Tips
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Always proxy AI requests through your own backend (Node.js, Laravel, or Firebase Functions).&lt;/li&gt;
&lt;li&gt;Use streaming (SSE or chunked responses) for chat-like experiences — it feels dramatically faster.&lt;/li&gt;
&lt;li&gt;Cache repeated prompts locally to reduce cost and latency.&lt;/li&gt;
&lt;li&gt;Set max token limits per request to control your AI spend.&lt;/li&gt;
&lt;li&gt;Use Riverpod or Bloc to keep AI state separate from UI state — makes testing much easier.&lt;/li&gt;
&lt;li&gt;Add retry logic with exponential backoff for rate-limited requests.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Visual Explanation Section
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;(Descriptions only — no images generated here)&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Architecture diagram&lt;/strong&gt;: Show the flow from Flutter UI → Backend Proxy → AI Provider, with arrows and labeled boxes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Chat app UI mockup&lt;/strong&gt;: Show a simple chat bubble interface with a streaming "typing" indicator.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Folder structure screenshot&lt;/strong&gt;: Show &lt;code&gt;lib/core&lt;/code&gt;, &lt;code&gt;lib/features&lt;/code&gt;, &lt;code&gt;lib/services&lt;/code&gt; organized cleanly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API response flow diagram&lt;/strong&gt;: Show request → backend validation → AI call → response → UI update.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Real-World Use Case
&lt;/h2&gt;

&lt;p&gt;This exact architecture pattern is used in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SaaS products&lt;/strong&gt; — AI-powered chat widgets embedded in customer dashboards.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mobile productivity apps&lt;/strong&gt; — journaling, note summarization, resume tools.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Admin panels&lt;/strong&gt; — turning raw analytics into plain-English summaries for non-technical teams.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;EdTech apps&lt;/strong&gt; — flashcard and study tools used by thousands of students daily.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The pattern scales from a solo indie app to a multi-tenant SaaS product without major rewrites.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Building Flutter + AI apps isn't about calling an API once — it's about architecture, security, and user experience working together.&lt;/p&gt;

&lt;p&gt;With the repeatable pattern shown here (UI → State → Repository → Backend Proxy → AI Provider), you can confidently build any of these 12 app ideas — and many more beyond them.&lt;/p&gt;

&lt;p&gt;Start small, pick one idea, and ship it end-to-end. That's how you go from prompt to product.&lt;/p&gt;




&lt;h2&gt;
  
  
  Want to build AI-powered mobile apps with Flutter?
&lt;/h2&gt;

&lt;p&gt;Learning AI integration by building small demos is a great way to understand the basics. But if you want to create real-world applications, you need more than just API calls , you need practical projects, proven architectures, and a clear roadmap.&lt;/p&gt;

&lt;p&gt;I created &lt;strong&gt;&lt;a href="https://cimoradevtools.gumroad.com/l/flutter-ai-projects" rel="noopener noreferrer"&gt;Build AI-Powered Mobile Apps with Flutter: 15 Real Projects&lt;/a&gt;&lt;/strong&gt; to help Flutter developers learn by building real applications.&lt;/p&gt;

&lt;p&gt;Inside this guide, you’ll discover how to build AI-powered apps including chat assistants, image generators, voice assistants, AI analyzers, productivity tools, and more.&lt;/p&gt;

&lt;p&gt;Each project includes the app idea, features, technology choices, development steps, architecture guidance, and ready-to-use AI coding prompts that help you build faster with tools like ChatGPT, Claude, and Cursor.&lt;/p&gt;

&lt;p&gt;Instead of spending weeks figuring out what to build and how to integrate AI, you can follow practical projects and turn ideas into working mobile applications.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://cimoradevtools.gumroad.com/l/flutter-ai-projects" rel="noopener noreferrer"&gt;Build AI-Powered Mobile Apps with Flutter: 15 Real Projects →&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;




</description>
      <category>ai</category>
      <category>flutter</category>
    </item>
    <item>
      <title>What Can You Actually Build With Flutter + AI in 2026? Here Are 15 Ideas</title>
      <dc:creator>Nabeel Krissane</dc:creator>
      <pubDate>Mon, 24 Aug 2026 10:00:40 +0000</pubDate>
      <link>https://dev.to/nabilkrs/what-can-you-actually-build-with-flutter-ai-in-2026-here-are-15-ideas-35bb</link>
      <guid>https://dev.to/nabilkrs/what-can-you-actually-build-with-flutter-ai-in-2026-here-are-15-ideas-35bb</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Every Flutter developer eventually hits the same wall: you know Flutter well, you've heard "AI is the future," but you have no idea what to actually &lt;em&gt;build&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Tutorials show you how to call an API. They rarely show you how to turn Flutter + AI into a real, shippable product.&lt;/p&gt;

&lt;p&gt;This matters because in 2026, apps that don't offer any intelligent feature — smart suggestions, chat assistants, image recognition, personalization — already feel outdated to users.&lt;/p&gt;

&lt;p&gt;In this article, you'll learn 15 practical Flutter + AI project ideas, complete with real code examples, common mistakes to avoid, and best practices for structuring these features in production apps. By the end, you'll know exactly what to build next.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Developers Struggle to Combine Flutter and AI
&lt;/h2&gt;

&lt;p&gt;Most Flutter developers understand widgets, state management, and API calls. AI integration feels different, and that difference causes three common problems:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. They think AI requires a data science background.&lt;/strong&gt;&lt;br&gt;
In reality, most Flutter + AI apps just call a cloud API (like OpenAI, Gemini, or a custom backend). No model training required.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. They don't know where AI logic should live.&lt;/strong&gt;&lt;br&gt;
Should the AI call happen in the widget? In a service class? In a backend? Without a clear pattern, apps become messy fast.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. They copy tutorial code that isn't production-ready.&lt;/strong&gt;&lt;br&gt;
No error handling, no loading states, no separation of concerns — it works once, then breaks in real usage.&lt;/p&gt;

&lt;p&gt;The good news: once you understand a simple, repeatable architecture, you can plug AI into almost any Flutter app idea below.&lt;/p&gt;


&lt;h2&gt;
  
  
  Solution Overview
&lt;/h2&gt;

&lt;p&gt;The pattern used across all 15 ideas below is the same:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Flutter UI captures user input (text, image, voice, or file)&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;service class&lt;/strong&gt; sends that input to an AI API&lt;/li&gt;
&lt;li&gt;The response is parsed and displayed in the UI&lt;/li&gt;
&lt;li&gt;State management (Provider, Riverpod, or Bloc) handles loading/error/success states&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Once you have this pattern down, every idea on this list becomes a variation of the same architecture.&lt;/p&gt;


&lt;h2&gt;
  
  
  Step-by-Step Implementation (Base Pattern)
&lt;/h2&gt;

&lt;p&gt;Let's build the foundation you'll reuse across every idea in this list: an &lt;strong&gt;AI Service Layer&lt;/strong&gt; in Flutter.&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 1: Setup
&lt;/h3&gt;

&lt;p&gt;Create a new Flutter project or use an existing one.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;flutter create ai_flutter_app
&lt;span class="nb"&gt;cd &lt;/span&gt;ai_flutter_app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the required packages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;dependencies&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;flutter&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;sdk&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;flutter&lt;/span&gt;
  &lt;span class="na"&gt;http&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^1.2.0&lt;/span&gt;
  &lt;span class="na"&gt;provider&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^6.1.2&lt;/span&gt;
  &lt;span class="na"&gt;flutter_dotenv&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^5.1.0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;flutter pub get
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Configuration
&lt;/h3&gt;

&lt;p&gt;Store your API key safely using &lt;code&gt;flutter_dotenv&lt;/code&gt;. Never hardcode API keys.&lt;/p&gt;

&lt;p&gt;Create a &lt;code&gt;.env&lt;/code&gt; file in the root folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;AI_API_KEY&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;your_api_key_here&lt;/span&gt;
&lt;span class="py"&gt;AI_API_URL&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;https://api.openai.com/v1/chat/completions&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Load it in &lt;code&gt;main.dart&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:flutter_dotenv/flutter_dotenv.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;dotenv&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;fileName:&lt;/span&gt; &lt;span class="s"&gt;".env"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;runApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;MyApp&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;h3&gt;
  
  
  Step 3: Core Implementation (AI Service Class)
&lt;/h3&gt;

&lt;p&gt;This is the reusable core you'll use in every project idea below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'dart:convert'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:http/http.dart'&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:flutter_dotenv/flutter_dotenv.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AIService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;_apiUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dotenv&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'AI_API_URL'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;_apiKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dotenv&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'AI_API_KEY'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;getAIResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&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="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="kt"&gt;Uri&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_apiUrl&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="nl"&gt;headers:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="s"&gt;'Content-Type'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'application/json'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s"&gt;'Authorization'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'Bearer &lt;/span&gt;&lt;span class="si"&gt;$_apiKey&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="nl"&gt;body:&lt;/span&gt; &lt;span class="n"&gt;jsonEncode&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
          &lt;span class="s"&gt;"model"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"gpt-4o-mini"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s"&gt;"messages"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"role"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"user"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"content"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;prompt&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;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;statusCode&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;jsonDecode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'choices'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s"&gt;'message'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s"&gt;'content'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="n"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'AI request failed: &lt;/span&gt;&lt;span class="si"&gt;${response.statusCode}&lt;/span&gt;&lt;span class="s"&gt;'&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;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="n"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Error fetching AI response: &lt;/span&gt;&lt;span class="si"&gt;$e&lt;/span&gt;&lt;span class="s"&gt;'&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;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What this does:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sends the user's prompt to the AI API&lt;/li&gt;
&lt;li&gt;Handles the HTTP request and response parsing&lt;/li&gt;
&lt;li&gt;Throws clear errors instead of failing silently&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 4: Final Integration (Connecting UI to the Service)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ChatScreen&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;StatefulWidget&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;ChatScreen&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ChatScreen&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;createState&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_ChatScreenState&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;_ChatScreenState&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ChatScreen&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;AIService&lt;/span&gt; &lt;span class="n"&gt;_aiService&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;AIService&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;TextEditingController&lt;/span&gt; &lt;span class="n"&gt;_controller&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TextEditingController&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;_response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;_isLoading&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_sendPrompt&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_isLoading&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_aiService&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getAIResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_controller&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="n"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'Something went wrong. Try again.'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_isLoading&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&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;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuildContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Scaffold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;appBar:&lt;/span&gt; &lt;span class="n"&gt;AppBar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;title:&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Flutter AI Demo'&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
      &lt;span class="nl"&gt;body:&lt;/span&gt; &lt;span class="n"&gt;Padding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;padding:&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;EdgeInsets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="nl"&gt;children:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="n"&gt;TextField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
              &lt;span class="nl"&gt;controller:&lt;/span&gt; &lt;span class="n"&gt;_controller&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="nl"&gt;decoration:&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;InputDecoration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;hintText:&lt;/span&gt; &lt;span class="s"&gt;'Ask something...'&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="n"&gt;SizedBox&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;height:&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="n"&gt;ElevatedButton&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
              &lt;span class="nl"&gt;onPressed:&lt;/span&gt; &lt;span class="n"&gt;_isLoading&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;_sendPrompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;_isLoading&lt;/span&gt;
                  &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;CircularProgressIndicator&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                  &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Ask AI'&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="n"&gt;SizedBox&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;height:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_response&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;span class="p"&gt;),&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;This gives you a working Flutter + AI chat screen with loading and error states — the base you'll reuse below.&lt;/p&gt;




&lt;h2&gt;
  
  
  15 Flutter + AI Project Ideas You Can Actually Build
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;AI Chat Assistant&lt;/strong&gt; — customer support bot inside your app using the pattern above.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Smart Journaling App&lt;/strong&gt; — AI summarizes and tags daily entries.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI Resume Builder&lt;/strong&gt; — user inputs experience, AI generates formatted resume text.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Image Caption Generator&lt;/strong&gt; — pair &lt;code&gt;image_picker&lt;/code&gt; with a vision API to auto-caption photos.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI Recipe Generator&lt;/strong&gt; — user lists ingredients, AI returns recipes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Voice-to-Task App&lt;/strong&gt; — speech-to-text input converted into structured to-do items.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI Study Buddy&lt;/strong&gt; — students paste notes, AI generates quiz questions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Smart Expense Categorizer&lt;/strong&gt; — AI classifies transactions from bank SMS/CSV imports.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI Code Explainer App&lt;/strong&gt; — paste code snippets, get plain-English explanations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Personalized Workout Planner&lt;/strong&gt; — AI generates plans based on user goals.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI Email/Message Composer&lt;/strong&gt; — generates professional replies from bullet points.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Product Description Generator&lt;/strong&gt; — for e-commerce seller apps.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI Travel Itinerary Planner&lt;/strong&gt; — input destination and days, get a full plan.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mood-Based Music/Content Recommender&lt;/strong&gt; — combine sentiment analysis with recommendations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI-Powered Admin Dashboard Assistant&lt;/strong&gt; — natural language queries over business data (e.g., "show me last month's top products").&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Each of these reuses the same &lt;code&gt;AIService&lt;/code&gt; pattern — only the prompt and UI change.&lt;/p&gt;




&lt;h2&gt;
  
  
  Common Mistakes Developers Make
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Hardcoding API keys in the codebase.&lt;/strong&gt;&lt;br&gt;
This exposes your key when the app is decompiled. Always use environment variables or a backend proxy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Calling AI APIs directly from the UI widget.&lt;/strong&gt;&lt;br&gt;
This tightly couples UI and logic, making testing and reuse painful. Always use a service class.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. No loading or error states.&lt;/strong&gt;&lt;br&gt;
AI responses can take 2–5 seconds. Without loading indicators, users think the app froze.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Sending unbounded user input.&lt;/strong&gt;&lt;br&gt;
Long prompts increase cost and latency. Always trim or validate input length.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Ignoring rate limits.&lt;/strong&gt;&lt;br&gt;
Spamming the API during testing can get your key throttled or banned. Add debouncing on user input.&lt;/p&gt;




&lt;h2&gt;
  
  
  Best Practices and Tips
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Use a backend proxy&lt;/strong&gt; (Node.js, Laravel, or Firebase Functions) between Flutter and the AI API in production. This hides your API key completely.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cache repeated responses&lt;/strong&gt; locally to reduce cost and latency.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stream responses&lt;/strong&gt; when possible for a better UX (typing effect instead of waiting for the full response).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use Riverpod or Bloc&lt;/strong&gt; for state management once your AI features grow past a single screen.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Set timeouts&lt;/strong&gt; on HTTP requests so the UI doesn't hang indefinitely.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Log failures&lt;/strong&gt; (not user data) to catch API issues early.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Visual Explanation Section
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;(Descriptions only — no images generated)&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Screenshot 1:&lt;/strong&gt; Flutter chat screen UI showing a text input field, "Ask AI" button, and a response bubble below it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Screenshot 2:&lt;/strong&gt; Folder structure showing &lt;code&gt;lib/services/ai_service.dart&lt;/code&gt;, &lt;code&gt;lib/screens/chat_screen.dart&lt;/code&gt;, and &lt;code&gt;.env&lt;/code&gt; file at the root.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Diagram:&lt;/strong&gt; A simple flow — &lt;code&gt;User Input → Flutter UI → AI Service → HTTP Request → AI API → JSON Response → Parsed Text → UI Update&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Real-World Use Cases
&lt;/h2&gt;

&lt;p&gt;This exact pattern is used in production apps today:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SaaS tools&lt;/strong&gt; use it for AI-powered onboarding assistants and support chat.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mobile productivity apps&lt;/strong&gt; use it for smart summarization and task generation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;E-commerce apps&lt;/strong&gt; use AI for product descriptions and personalized recommendations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Admin dashboards&lt;/strong&gt; use natural language queries to let non-technical staff pull data without writing SQL.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The architecture doesn't change between these — only the prompt and the UI layer do.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Flutter + AI isn't about building complex machine learning models. It's about wiring a clean service layer to a capable AI API and designing a UI that handles loading, errors, and responses gracefully.&lt;/p&gt;

&lt;p&gt;With the base pattern from this article, you can build any of the 15 ideas listed above — and dozens more — without starting from scratch each time.&lt;/p&gt;

&lt;p&gt;The key takeaway: master one solid AI service architecture, and every new "AI feature" becomes a small variation, not a new problem.&lt;/p&gt;




&lt;h2&gt;
  
  
  Want to build AI-powered mobile apps with Flutter?
&lt;/h2&gt;

&lt;p&gt;Learning AI integration by building small demos is a great way to understand the basics. But if you want to create real-world applications, you need more than just API calls , you need practical projects, proven architectures, and a clear roadmap.&lt;/p&gt;

&lt;p&gt;I created &lt;strong&gt;&lt;a href="https://cimoradevtools.gumroad.com/l/flutter-ai-projects" rel="noopener noreferrer"&gt;Build AI-Powered Mobile Apps with Flutter: 15 Real Projects&lt;/a&gt;&lt;/strong&gt; to help Flutter developers learn by building real applications.&lt;/p&gt;

&lt;p&gt;Inside this guide, you’ll discover how to build AI-powered apps including chat assistants, image generators, voice assistants, AI analyzers, productivity tools, and more.&lt;/p&gt;

&lt;p&gt;Each project includes the app idea, features, technology choices, development steps, architecture guidance, and ready-to-use AI coding prompts that help you build faster with tools like ChatGPT, Claude, and Cursor.&lt;/p&gt;

&lt;p&gt;Instead of spending weeks figuring out what to build and how to integrate AI, you can follow practical projects and turn ideas into working mobile applications.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://cimoradevtools.gumroad.com/l/flutter-ai-projects" rel="noopener noreferrer"&gt;Build AI-Powered Mobile Apps with Flutter: 15 Real Projects →&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>flutter</category>
    </item>
    <item>
      <title>I Stopped Asking Cursor to “Fix My Code” Here’s What I Do Instead</title>
      <dc:creator>Nabeel Krissane</dc:creator>
      <pubDate>Thu, 20 Aug 2026 06:06:55 +0000</pubDate>
      <link>https://dev.to/nabilkrs/i-stopped-asking-cursor-to-fix-my-code-heres-what-i-do-instead-kkp</link>
      <guid>https://dev.to/nabilkrs/i-stopped-asking-cursor-to-fix-my-code-heres-what-i-do-instead-kkp</guid>
      <description>&lt;p&gt;Cursor is one of the most powerful AI coding editors available today. But if you've used it on a real React codebase, you've probably hit this frustrating pattern: you ask for a small change, and Cursor rewrites half your component, breaks your state logic, or introduces bugs that weren't there before.&lt;/p&gt;

&lt;p&gt;This isn't bad luck. It's a predictable problem with a predictable fix.&lt;/p&gt;

&lt;p&gt;In this article, you'll learn exactly why Cursor keeps breaking your React code, the mistakes most developers make when prompting it, and the practical workflow that keeps your codebase stable while still using AI to move fast.&lt;/p&gt;

&lt;p&gt;By the end, you'll have a repeatable system for using Cursor on React projects without babysitting every change.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem: Why Cursor Breaks React Code
&lt;/h2&gt;

&lt;p&gt;Cursor is an LLM working on your codebase, not a developer who understands your architecture. That distinction matters more in React than almost any other framework.&lt;/p&gt;

&lt;p&gt;Here's why:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. React has invisible context (state, props, hooks)&lt;/strong&gt;&lt;br&gt;
Cursor sees the file you're editing, but it doesn't always fully trace how state flows through parent components, context providers, or custom hooks. When it "fixes" a bug, it can quietly break a dependency it never saw.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Large, vague prompts cause large, vague edits&lt;/strong&gt;&lt;br&gt;
When you ask Cursor to "refactor this component" without scope, it interprets that broadly. It may rename variables, restructure JSX, or change hook order — all in one pass.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. It doesn't know your conventions&lt;/strong&gt;&lt;br&gt;
Cursor doesn't know your team uses Zustand instead of Redux, or that you never use &lt;code&gt;useEffect&lt;/code&gt; for derived state. Without guardrails, it defaults to generic React patterns that clash with your codebase.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Multi-file changes are riskier than they look&lt;/strong&gt;&lt;br&gt;
React components are rarely isolated. A prop type change in one file can silently break three others. Cursor doesn't always catch the ripple effect.&lt;/p&gt;

&lt;p&gt;The common developer mistake? Treating Cursor like a senior engineer who "just knows" the codebase, instead of treating it like a fast junior dev who needs clear instructions and boundaries.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Solution Overview
&lt;/h2&gt;

&lt;p&gt;The fix isn't to stop using Cursor. It's to change &lt;strong&gt;how&lt;/strong&gt; you prompt it and &lt;strong&gt;how&lt;/strong&gt; you review its output.&lt;/p&gt;

&lt;p&gt;The core idea:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Scope every request tightly&lt;/li&gt;
&lt;li&gt;Give Cursor the right context before it edits&lt;/li&gt;
&lt;li&gt;Review diffs like a code review, not a rubber stamp&lt;/li&gt;
&lt;li&gt;Use rules files to enforce your project's conventions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's implement this step by step.&lt;/p&gt;


&lt;h2&gt;
  
  
  Step-by-Step Implementation
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Step 1: Setup — Give Cursor Project Context
&lt;/h3&gt;

&lt;p&gt;Before writing any prompts, set up a &lt;code&gt;.cursorrules&lt;/code&gt; file at your project root. This tells Cursor how your React project works.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# .cursorrules

- This is a React + TypeScript project using functional components only.
- State management: Zustand (no Redux, no Context API for global state).
- Styling: Tailwind CSS only. No inline styles, no CSS modules.
- Do not modify files outside the current task scope.
- Always preserve existing prop types unless explicitly asked to change them.
- Prefer small, isolated changes over large refactors.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This single file eliminates most of Cursor's "guessing" behavior.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Configuration — Scope Cursor to Specific Files
&lt;/h3&gt;

&lt;p&gt;Instead of letting Cursor search your whole repo, manually attach only the relevant files using &lt;code&gt;@filename&lt;/code&gt; references.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Button.tsx @useCartStore.ts

Update the Button component to show a loading spinner 
when `isLoading` is true. Do not change existing props.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This prevents Cursor from touching unrelated files it "thinks" are connected.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Core Implementation — Write Scoped, Specific Prompts
&lt;/h3&gt;

&lt;p&gt;Vague prompts produce vague (and dangerous) edits. Compare these two:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;❌ Risky prompt:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Refactor this component to be cleaner.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;✅ Safe prompt:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;In CartSummary.tsx, extract the total price calculation 
into a separate function called `calculateTotal`. 
Do not change any JSX or component structure.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second prompt gives Cursor a clear boundary. It knows exactly what to touch and what to leave alone.&lt;/p&gt;

&lt;p&gt;Here's a real example of a safe, scoped fix:&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="c1"&gt;// Before&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;CartSummary&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;items&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CartItem&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;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;item&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;sum&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;price&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;qty&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&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;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-lg font-semibold"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Total: $&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;total&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// After (Cursor's scoped edit)&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;calculateTotal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CartItem&lt;/span&gt;&lt;span class="p"&gt;[]):&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;item&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;sum&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;price&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;qty&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;CartSummary&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;items&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CartItem&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;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;calculateTotal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;items&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;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-lg font-semibold"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Total: $&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;total&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice nothing else changed — no renamed props, no restructured JSX.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Final Integration — Review Before Accepting
&lt;/h3&gt;

&lt;p&gt;Never click "Accept All" on a multi-file change without reviewing the diff.&lt;/p&gt;

&lt;p&gt;A simple review checklist:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Did any prop types change unexpectedly?&lt;/li&gt;
&lt;li&gt;Did hook order change?&lt;/li&gt;
&lt;li&gt;Were any imports removed that are still used elsewhere?&lt;/li&gt;
&lt;li&gt;Did styling classes get altered outside the requested scope?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cursor's diff view makes this fast — use it every time, not just for big changes.&lt;/p&gt;




&lt;h2&gt;
  
  
  Common Mistakes Developers Make
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Mistake 1: Asking for multiple things in one prompt&lt;/strong&gt;&lt;br&gt;
"Fix the bug and also clean up the styling and rename this" — Cursor tries to do all three at once, increasing risk.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mistake 2: Not attaching the right files&lt;/strong&gt;&lt;br&gt;
Without &lt;code&gt;@filename&lt;/code&gt; context, Cursor guesses which files matter, and guesses wrong more often than expected.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mistake 3: Skipping the &lt;code&gt;.cursorrules&lt;/code&gt; file&lt;/strong&gt;&lt;br&gt;
This is the single most skipped setup step, and it's the reason most "Cursor broke my code" complaints happen.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mistake 4: Accepting changes without reading the diff&lt;/strong&gt;&lt;br&gt;
AI-generated code looks correct at a glance. Bugs often hide in logic, not syntax.&lt;/p&gt;




&lt;h2&gt;
  
  
  Best Practices and Tips
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Keep prompts scoped to one component or one function at a time&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;.cursorrules&lt;/code&gt; to lock in architecture decisions&lt;/li&gt;
&lt;li&gt;Commit before big AI-assisted refactors, so you can roll back instantly&lt;/li&gt;
&lt;li&gt;Use TypeScript — it catches many AI-introduced errors automatically&lt;/li&gt;
&lt;li&gt;For complex state logic, write the logic yourself and let Cursor handle boilerplate instead&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Performance tip:&lt;/strong&gt; Cursor tends to over-add &lt;code&gt;useEffect&lt;/code&gt; calls. Always double-check if the logic could be derived during render instead.&lt;/p&gt;




&lt;h2&gt;
  
  
  Visual Explanation Section
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;(Add screenshots here for Medium)&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Screenshot 1:&lt;/strong&gt; Show the &lt;code&gt;.cursorrules&lt;/code&gt; file open in the editor sidebar&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Screenshot 2:&lt;/strong&gt; Show Cursor's diff view with an accepted vs. rejected change highlighted&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Screenshot 3:&lt;/strong&gt; Show a folder structure with &lt;code&gt;.cursorrules&lt;/code&gt; at the project root&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Diagram:&lt;/strong&gt; A simple flow showing "Vague Prompt → Broad Edit → Bugs" vs "Scoped Prompt → Isolated Edit → Stable Code"&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Real-World Use Case
&lt;/h2&gt;

&lt;p&gt;This workflow matters most in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SaaS dashboards&lt;/strong&gt;, where shared components (buttons, tables, modals) are reused across dozens of pages — one bad AI edit can break multiple screens.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Production e-commerce apps&lt;/strong&gt;, where state management bugs directly affect checkout flows.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Admin panels&lt;/strong&gt;, where role-based UI logic is easy for AI to misinterpret without proper context.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Teams that adopt &lt;code&gt;.cursorrules&lt;/code&gt; and scoped prompting report far fewer regressions from AI-assisted changes, especially in shared component libraries.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Cursor doesn't break React code because it's a bad tool — it breaks React code when it's used without context, scope, or review.&lt;/p&gt;

&lt;p&gt;To recap:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set up a &lt;code&gt;.cursorrules&lt;/code&gt; file to lock in your project's conventions&lt;/li&gt;
&lt;li&gt;Attach only relevant files to each prompt&lt;/li&gt;
&lt;li&gt;Write scoped, specific prompts instead of vague ones&lt;/li&gt;
&lt;li&gt;Always review diffs before accepting changes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Follow this workflow, and Cursor becomes a genuine productivity boost instead of a source of new bugs.&lt;/p&gt;




&lt;h2&gt;
  
  
  Want to get better results from Cursor when building React apps?
&lt;/h2&gt;

&lt;p&gt;AI coding assistants can make React development dramatically faster. But the quality of the result often depends on how you communicate with the AI.&lt;/p&gt;

&lt;p&gt;A simple prompt like &lt;em&gt;“fix this bug”&lt;/em&gt; or &lt;em&gt;“refactor this component”&lt;/em&gt; can produce inconsistent results. The better approach is to give Cursor the right context, constraints, development steps, and validation instructions.&lt;/p&gt;

&lt;p&gt;That’s why I created &lt;strong&gt;&lt;a href="https://cimoradevtools.gumroad.com/l/ultimate-react-cursor-prompt-library" rel="noopener noreferrer"&gt;The Ultimate React + Cursor Prompt Library — 1000+ AI Prompts&lt;/a&gt;&lt;/strong&gt;: a practical AI-powered development toolkit designed for real-world React projects.&lt;/p&gt;

&lt;p&gt;Inside the library, you’ll find &lt;strong&gt;1,000+ practical prompts&lt;/strong&gt; covering the entire React development workflow, including building UI components, integrating APIs, authentication, state management, debugging, refactoring, performance optimization, testing, deployment, architecture, and more.&lt;/p&gt;

&lt;p&gt;The prompts are designed to help Cursor:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Understand your existing codebase before making changes&lt;/li&gt;
&lt;li&gt;Find root causes instead of applying random fixes&lt;/li&gt;
&lt;li&gt;Make targeted changes without unnecessary rewrites&lt;/li&gt;
&lt;li&gt;Preserve existing functionality&lt;/li&gt;
&lt;li&gt;Refactor code safely&lt;/li&gt;
&lt;li&gt;Improve performance&lt;/li&gt;
&lt;li&gt;Write and improve tests&lt;/li&gt;
&lt;li&gt;Validate changes before you ship&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of spending time figuring out how to phrase every request to your AI coding assistant, you can start with a structured prompt designed for the specific development problem you’re trying to solve.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Better prompts → Better React code.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://cimoradevtools.gumroad.com/l/ultimate-react-cursor-prompt-library" rel="noopener noreferrer"&gt;&lt;strong&gt;Get The Ultimate React + Cursor Prompt Library →&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>ai</category>
      <category>promptengineering</category>
      <category>javascript</category>
    </item>
    <item>
      <title>How to Structure a Flutter App Using Clean Architecture</title>
      <dc:creator>Nabeel Krissane</dc:creator>
      <pubDate>Thu, 21 May 2026 15:15:24 +0000</pubDate>
      <link>https://dev.to/nabilkrs/how-to-structure-a-flutter-app-using-clean-architecture-3ejd</link>
      <guid>https://dev.to/nabilkrs/how-to-structure-a-flutter-app-using-clean-architecture-3ejd</guid>
      <description>&lt;p&gt;&lt;em&gt;Stop building apps that collapse under their own weight. Here's the structure that actually scales.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;You ship your first Flutter app. It works. Users come in. Features pile up. Six months later, you're afraid to touch anything because one change breaks three other things.&lt;/p&gt;

&lt;p&gt;Sound familiar?&lt;/p&gt;

&lt;p&gt;This is what happens when Flutter apps grow without a clear architecture. Business logic bleeds into widgets. API calls live inside &lt;code&gt;initState&lt;/code&gt;. State management becomes a mess of &lt;code&gt;setState&lt;/code&gt; calls scattered everywhere.&lt;/p&gt;

&lt;p&gt;The fix is &lt;strong&gt;Flutter Clean Architecture&lt;/strong&gt; — a battle-tested pattern that separates your app into distinct layers, each with one responsibility. In this guide, you'll learn how to set up a production-ready Flutter Clean Architecture boilerplate from scratch, with real code examples, a Laravel backend integration, and authentication built in.&lt;/p&gt;

&lt;p&gt;By the end, you'll have a foundation you can drop into any real-world project.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem: Why Flutter Apps Become Unmaintainable
&lt;/h2&gt;

&lt;p&gt;Most Flutter tutorials show you &lt;em&gt;how&lt;/em&gt; to build a feature. Almost none show you &lt;em&gt;where&lt;/em&gt; to put it.&lt;/p&gt;

&lt;p&gt;So developers do what feels natural:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Call the API directly from the widget&lt;/li&gt;
&lt;li&gt;Store state in a top-level variable&lt;/li&gt;
&lt;li&gt;Put business rules inside the UI layer&lt;/li&gt;
&lt;li&gt;Duplicate logic across screens because there's no shared structure&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This works fine at 3 screens. At 30 screens, it's a nightmare.&lt;/p&gt;

&lt;p&gt;The result: slow onboarding for new teammates, fear of refactoring, and bugs that reappear in unexpected places. The app becomes fragile — and the codebase becomes a liability.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Solution: Flutter Clean Architecture
&lt;/h2&gt;

&lt;p&gt;Clean Architecture, popularized by Robert C. Martin, organizes code into &lt;strong&gt;three independent layers&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Presentation Layer&lt;/strong&gt; — UI widgets, state management (BLoC/Cubit)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Domain Layer&lt;/strong&gt; — Business logic, use cases, abstract repository interfaces&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data Layer&lt;/strong&gt; — API calls, local storage, concrete repository implementations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each layer only talks to the layer directly below it. Your widgets never know what database you use. Your business logic never imports a Flutter widget. This separation makes testing easy, onboarding fast, and refactoring safe.&lt;/p&gt;

&lt;p&gt;Let's build it.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 1: Project Setup and Folder Structure
&lt;/h2&gt;

&lt;p&gt;Start by creating your Flutter project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;flutter create my_app
&lt;span class="nb"&gt;cd &lt;/span&gt;my_app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now structure your &lt;code&gt;lib/&lt;/code&gt; folder like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;lib/
├── core/
│   ├── error/
│   │   ├── exceptions.dart
│   │   └── failures.dart
│   ├── network/
│   │   └── api_client.dart
│   └── utils/
│       └── constants.dart
├── features/
│   └── auth/
│       ├── data/
│       │   ├── datasources/
│       │   │   └── auth_remote_datasource.dart
│       │   ├── models/
│       │   │   └── user_model.dart
│       │   └── repositories/
│       │       └── auth_repository_impl.dart
│       ├── domain/
│       │   ├── entities/
│       │   │   └── user.dart
│       │   ├── repositories/
│       │   │   └── auth_repository.dart
│       │   └── usecases/
│       │       └── login_usecase.dart
│       └── presentation/
│           ├── bloc/
│           │   ├── auth_bloc.dart
│           │   ├── auth_event.dart
│           │   └── auth_state.dart
│           └── pages/
│               └── login_page.dart
└── injection_container.dart
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Visual:&lt;/strong&gt; Here you should show the full folder tree in your IDE (VS Code or Android Studio). Highlight the &lt;code&gt;features/auth/&lt;/code&gt; directory and show how data, domain, and presentation sit side by side inside each feature.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Step 2: Install Dependencies
&lt;/h2&gt;

&lt;p&gt;Add these to your &lt;code&gt;pubspec.yaml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;dependencies&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;flutter&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;sdk&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;flutter&lt;/span&gt;
  &lt;span class="na"&gt;flutter_bloc&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^8.1.3&lt;/span&gt;
  &lt;span class="na"&gt;dio&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^5.3.2&lt;/span&gt;
  &lt;span class="na"&gt;get_it&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^7.6.4&lt;/span&gt;
  &lt;span class="na"&gt;dartz&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^0.10.1&lt;/span&gt;
  &lt;span class="na"&gt;equatable&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^2.0.5&lt;/span&gt;
  &lt;span class="na"&gt;shared_preferences&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^2.2.2&lt;/span&gt;

&lt;span class="na"&gt;dev_dependencies&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;flutter_test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;sdk&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;flutter&lt;/span&gt;
  &lt;span class="na"&gt;mockito&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^5.4.2&lt;/span&gt;
  &lt;span class="na"&gt;build_runner&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^2.4.6&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;flutter pub get
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why these packages?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;flutter_bloc&lt;/code&gt; — State management&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;dio&lt;/code&gt; — HTTP client for API calls (works great with Laravel)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;get_it&lt;/code&gt; — Dependency injection&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;dartz&lt;/code&gt; — Functional error handling with &lt;code&gt;Either&amp;lt;Failure, Success&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;equatable&lt;/code&gt; — Value equality for entities and states&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Step 3: Core Implementation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  3.1 Define Failures and Exceptions
&lt;/h3&gt;

&lt;p&gt;In Clean Architecture, errors flow upward through layers. Define them clearly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="c1"&gt;// lib/core/error/exceptions.dart&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ServerException&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="n"&gt;Exception&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;ServerException&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="kd"&gt;required&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CacheException&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="n"&gt;Exception&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;CacheException&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="kd"&gt;required&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;message&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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="c1"&gt;// lib/core/error/failures.dart&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:equatable/equatable.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;abstract&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Failure&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;Equatable&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Failure&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="kd"&gt;required&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="kt"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="n"&gt;props&lt;/span&gt; &lt;span class="o"&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="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ServerFailure&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;Failure&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;ServerFailure&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="kd"&gt;required&lt;/span&gt; &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CacheFailure&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;Failure&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;CacheFailure&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="kd"&gt;required&lt;/span&gt; &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;message&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;h3&gt;
  
  
  3.2 Set Up the API Client (Dio + Laravel)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="c1"&gt;// lib/core/network/api_client.dart&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:dio/dio.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ApiClient&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;late&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;Dio&lt;/span&gt; &lt;span class="n"&gt;_dio&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="n"&gt;ApiClient&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;_dio&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Dio&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="n"&gt;BaseOptions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;baseUrl:&lt;/span&gt; &lt;span class="s"&gt;'https://your-laravel-app.com/api'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nl"&gt;connectTimeout:&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Duration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;seconds:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="nl"&gt;receiveTimeout:&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Duration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;seconds:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="nl"&gt;headers:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="s"&gt;'Accept'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'application/json'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s"&gt;'Content-Type'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'application/json'&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;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;_dio&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;interceptors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="n"&gt;InterceptorsWrapper&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;onRequest:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="c1"&gt;// Attach Bearer token for Laravel Sanctum / Passport&lt;/span&gt;
          &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// retrieve from storage&lt;/span&gt;
          &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isNotEmpty&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'Authorization'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'Bearer &lt;/span&gt;&lt;span class="si"&gt;$token&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="nl"&gt;onError:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DioException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&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;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="n"&gt;Dio&lt;/span&gt; &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="n"&gt;dio&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_dio&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;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Visual:&lt;/strong&gt; Here you should show an API response flow diagram. Arrow from Flutter app → Dio Client → Laravel &lt;code&gt;/api/login&lt;/code&gt; → JSON response → model parsing → entity → BLoC state.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Step 4: The Authentication Feature — End to End
&lt;/h2&gt;

&lt;p&gt;This is the most common real-world feature. Let's build it across all three layers.&lt;/p&gt;

&lt;h3&gt;
  
  
  4.1 Domain Layer — The Pure Core
&lt;/h3&gt;

&lt;p&gt;The domain layer has zero Flutter or Dart-specific framework dependencies. It's plain Dart.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="c1"&gt;// lib/features/auth/domain/entities/user.dart&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:equatable/equatable.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;Equatable&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="kd"&gt;required&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="kd"&gt;required&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="kd"&gt;required&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="kd"&gt;required&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="kt"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="n"&gt;props&lt;/span&gt; &lt;span class="o"&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="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;token&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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="c1"&gt;// lib/features/auth/domain/repositories/auth_repository.dart&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:dartz/dartz.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'../../../../core/error/failures.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'../entities/user.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;abstract&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AuthRepository&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Either&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Failure&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;login&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="kd"&gt;required&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="kd"&gt;required&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Either&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Failure&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;logout&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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="c1"&gt;// lib/features/auth/domain/usecases/login_usecase.dart&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:dartz/dartz.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'../../../../core/error/failures.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'../entities/user.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'../repositories/auth_repository.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LoginUseCase&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;AuthRepository&lt;/span&gt; &lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="n"&gt;LoginUseCase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;repository&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Either&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Failure&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="kd"&gt;required&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="kd"&gt;required&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;email:&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;password:&lt;/span&gt; &lt;span class="n"&gt;password&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;h3&gt;
  
  
  4.2 Data Layer — API Integration with Laravel
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="c1"&gt;// lib/features/auth/data/models/user_model.dart&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'../../domain/entities/user.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserModel&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;UserModel&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="kd"&gt;required&lt;/span&gt; &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="kd"&gt;required&lt;/span&gt; &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="kd"&gt;required&lt;/span&gt; &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="kd"&gt;required&lt;/span&gt; &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="kd"&gt;factory&lt;/span&gt; &lt;span class="n"&gt;UserModel&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromJson&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;dynamic&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;UserModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;id:&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'user'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="nl"&gt;name:&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'user'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="nl"&gt;email:&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'user'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s"&gt;'email'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="nl"&gt;token:&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'token'&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;span class="kt"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;dynamic&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;toJson&lt;/span&gt;&lt;span class="p"&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="s"&gt;'id'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s"&gt;'name'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s"&gt;'email'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s"&gt;'token'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;token&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;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="c1"&gt;// lib/features/auth/data/datasources/auth_remote_datasource.dart&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'../../../../core/error/exceptions.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'../../../../core/network/api_client.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'../models/user_model.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;abstract&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AuthRemoteDataSource&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;UserModel&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;login&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="kd"&gt;required&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;required&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AuthRemoteDataSourceImpl&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="n"&gt;AuthRemoteDataSource&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;ApiClient&lt;/span&gt; &lt;span class="n"&gt;apiClient&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="n"&gt;AuthRemoteDataSourceImpl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;apiClient&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;UserModel&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;login&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="kd"&gt;required&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="kd"&gt;required&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&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="n"&gt;apiClient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;dio&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="s"&gt;'/login'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nl"&gt;data:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;'email'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'password'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;statusCode&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;UserModel&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromJson&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="n"&gt;ServerException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;message:&lt;/span&gt; &lt;span class="s"&gt;'Login failed'&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;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="n"&gt;ServerException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;message:&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toString&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;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="c1"&gt;// lib/features/auth/data/repositories/auth_repository_impl.dart&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:dartz/dartz.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'../../../../core/error/exceptions.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'../../../../core/error/failures.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'../../domain/entities/user.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'../../domain/repositories/auth_repository.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'../datasources/auth_remote_datasource.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AuthRepositoryImpl&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="n"&gt;AuthRepository&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;AuthRemoteDataSource&lt;/span&gt; &lt;span class="n"&gt;remoteDataSource&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="n"&gt;AuthRepositoryImpl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;remoteDataSource&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Either&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Failure&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;login&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="kd"&gt;required&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="kd"&gt;required&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;remoteDataSource&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;email:&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nl"&gt;password:&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Right&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="kd"&gt;on&lt;/span&gt; &lt;span class="n"&gt;ServerException&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Left&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ServerFailure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;message:&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;message&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;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Either&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Failure&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;logout&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Clear token from storage&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Right&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&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;h3&gt;
  
  
  4.3 Presentation Layer — BLoC + UI
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="c1"&gt;// lib/features/auth/presentation/bloc/auth_event.dart&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:equatable/equatable.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;abstract&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AuthEvent&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;Equatable&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="kt"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="n"&gt;props&lt;/span&gt; &lt;span class="o"&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;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LoginRequested&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;AuthEvent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="n"&gt;LoginRequested&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="kd"&gt;required&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;required&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="kt"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="n"&gt;props&lt;/span&gt; &lt;span class="o"&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="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;password&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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="c1"&gt;// lib/features/auth/presentation/bloc/auth_state.dart&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:equatable/equatable.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'../../domain/entities/user.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;abstract&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AuthState&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;Equatable&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="kt"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="n"&gt;props&lt;/span&gt; &lt;span class="o"&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;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AuthInitial&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;AuthState&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AuthLoading&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;AuthState&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AuthSuccess&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;AuthState&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;AuthSuccess&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="kt"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="n"&gt;props&lt;/span&gt; &lt;span class="o"&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="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AuthFailure&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;AuthState&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;AuthFailure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="kt"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="n"&gt;props&lt;/span&gt; &lt;span class="o"&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="n"&gt;message&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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="c1"&gt;// lib/features/auth/presentation/bloc/auth_bloc.dart&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:flutter_bloc/flutter_bloc.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'../../domain/usecases/login_usecase.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'auth_event.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'auth_state.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AuthBloc&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;Bloc&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;AuthEvent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;AuthState&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;LoginUseCase&lt;/span&gt; &lt;span class="n"&gt;loginUseCase&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="n"&gt;AuthBloc&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="kd"&gt;required&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;loginUseCase&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AuthInitial&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;on&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;LoginRequested&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;_onLoginRequested&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_onLoginRequested&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;LoginRequested&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Emitter&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;AuthState&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;emit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;emit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AuthLoading&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

    &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;loginUseCase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;email:&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;password:&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;failure&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;emit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AuthFailure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;failure&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;emit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AuthSuccess&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&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;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="c1"&gt;// lib/features/auth/presentation/pages/login_page.dart&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:flutter/material.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:flutter_bloc/flutter_bloc.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'../bloc/auth_bloc.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'../bloc/auth_event.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'../bloc/auth_state.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LoginPage&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;StatefulWidget&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;LoginPage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;LoginPage&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;createState&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_LoginPageState&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;_LoginPageState&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;LoginPage&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;_emailController&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TextEditingController&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;_passwordController&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TextEditingController&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuildContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Scaffold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;appBar:&lt;/span&gt; &lt;span class="n"&gt;AppBar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;title:&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Login'&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
      &lt;span class="nl"&gt;body:&lt;/span&gt; &lt;span class="n"&gt;BlocConsumer&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;AuthBloc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;AuthState&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;listener:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="n"&gt;AuthSuccess&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Navigator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;pushReplacementNamed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'/home'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="n"&gt;AuthFailure&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;ScaffoldMessenger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;showSnackBar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
              &lt;span class="n"&gt;SnackBar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;content:&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;message&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;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="nl"&gt;builder:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Padding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nl"&gt;padding:&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;EdgeInsets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;24.0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
              &lt;span class="nl"&gt;mainAxisAlignment:&lt;/span&gt; &lt;span class="n"&gt;MainAxisAlignment&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;center&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="nl"&gt;children:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                &lt;span class="n"&gt;TextField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                  &lt;span class="nl"&gt;controller:&lt;/span&gt; &lt;span class="n"&gt;_emailController&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                  &lt;span class="nl"&gt;decoration:&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;InputDecoration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;labelText:&lt;/span&gt; &lt;span class="s"&gt;'Email'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                  &lt;span class="nl"&gt;keyboardType:&lt;/span&gt; &lt;span class="n"&gt;TextInputType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;emailAddress&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="n"&gt;SizedBox&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;height:&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                &lt;span class="n"&gt;TextField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                  &lt;span class="nl"&gt;controller:&lt;/span&gt; &lt;span class="n"&gt;_passwordController&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                  &lt;span class="nl"&gt;decoration:&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;InputDecoration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;labelText:&lt;/span&gt; &lt;span class="s"&gt;'Password'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                  &lt;span class="nl"&gt;obscureText:&lt;/span&gt; &lt;span class="kc"&gt;true&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="n"&gt;SizedBox&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;height:&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="n"&gt;AuthLoading&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;CircularProgressIndicator&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                &lt;span class="k"&gt;else&lt;/span&gt;
                  &lt;span class="n"&gt;ElevatedButton&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                    &lt;span class="nl"&gt;onPressed:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                      &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;read&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;AuthBloc&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                        &lt;span class="n"&gt;LoginRequested&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                          &lt;span class="nl"&gt;email:&lt;/span&gt; &lt;span class="n"&gt;_emailController&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                          &lt;span class="nl"&gt;password:&lt;/span&gt; &lt;span class="n"&gt;_passwordController&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;text&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;span class="p"&gt;},&lt;/span&gt;
                    &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Login'&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;span class="p"&gt;),&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;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;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Visual:&lt;/strong&gt; Here you should show the Flutter login screen UI — a clean form with email/password fields, a loading indicator state, and a success navigation transition. Screenshot from the emulator or device.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  4.4 Dependency Injection with GetIt
&lt;/h3&gt;

&lt;p&gt;Wire everything together in one place:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="c1"&gt;// lib/injection_container.dart&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:get_it/get_it.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'core/network/api_client.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'features/auth/data/datasources/auth_remote_datasource.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'features/auth/data/repositories/auth_repository_impl.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'features/auth/domain/repositories/auth_repository.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'features/auth/domain/usecases/login_usecase.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'features/auth/presentation/bloc/auth_bloc.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;sl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;GetIt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;init&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// BLoC&lt;/span&gt;
  &lt;span class="n"&gt;sl&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;registerFactory&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;AuthBloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;loginUseCase:&lt;/span&gt; &lt;span class="n"&gt;sl&lt;/span&gt;&lt;span class="p"&gt;()));&lt;/span&gt;

  &lt;span class="c1"&gt;// Use Cases&lt;/span&gt;
  &lt;span class="n"&gt;sl&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;registerLazySingleton&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;LoginUseCase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sl&lt;/span&gt;&lt;span class="p"&gt;()));&lt;/span&gt;

  &lt;span class="c1"&gt;// Repositories&lt;/span&gt;
  &lt;span class="n"&gt;sl&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;registerLazySingleton&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;AuthRepository&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;
    &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;AuthRepositoryImpl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sl&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Data Sources&lt;/span&gt;
  &lt;span class="n"&gt;sl&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;registerLazySingleton&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;AuthRemoteDataSource&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;
    &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;AuthRemoteDataSourceImpl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sl&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Core&lt;/span&gt;
  &lt;span class="n"&gt;sl&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;registerLazySingleton&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ApiClient&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;Call &lt;code&gt;init()&lt;/code&gt; in your &lt;code&gt;main.dart&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="c1"&gt;// lib/main.dart&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:flutter/material.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:flutter_bloc/flutter_bloc.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'features/auth/presentation/bloc/auth_bloc.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'features/auth/presentation/pages/login_page.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'injection_container.dart'&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;di&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;WidgetsFlutterBinding&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ensureInitialized&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;di&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;init&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="n"&gt;runApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;MyApp&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyApp&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;StatelessWidget&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;MyApp&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuildContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;MaterialApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;title:&lt;/span&gt; &lt;span class="s"&gt;'Clean App'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;home:&lt;/span&gt; &lt;span class="n"&gt;BlocProvider&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;create:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;di&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sl&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;AuthBloc&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(),&lt;/span&gt;
        &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;LoginPage&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;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;
  
  
  Laravel Backend — What the API Should Return
&lt;/h2&gt;

&lt;p&gt;Your Laravel &lt;code&gt;/api/login&lt;/code&gt; endpoint should return:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"token"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1|abcdefg12345"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"user"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Ahmed Ben Ali"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ahmed@example.com"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A simple Laravel controller using Sanctum:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;// app/Http/Controllers/Api/AuthController.php
&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;App\Http\Controllers\Api&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;App\Http\Controllers\Controller&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;App\Models\User&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Http\Request&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Support\Facades\Hash&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AuthController&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Controller&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Request&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
            &lt;span class="s1"&gt;'email'&lt;/span&gt;    &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'required|email'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'password'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'required'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;]);&lt;/span&gt;

        &lt;span class="nv"&gt;$user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'email'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nc"&gt;Hash&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;response&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
                &lt;span class="s1"&gt;'message'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'Invalid credentials'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;401&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;response&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
            &lt;span class="s1"&gt;'token'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;createToken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'flutter-app'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;plainTextToken&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'user'&lt;/span&gt;  &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;only&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'email'&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;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Visual:&lt;/strong&gt; Here you should show the API response flow — diagram with Laravel Sanctum token generation on the server side, and the Flutter model parsing the JSON into a &lt;code&gt;UserModel&lt;/code&gt;, then converting to a &lt;code&gt;User&lt;/code&gt; entity.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Common Mistakes Developers Make
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Importing Flutter packages in the domain layer&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The domain layer must stay pure Dart. Never import &lt;code&gt;package:flutter&lt;/code&gt; there. If you need &lt;code&gt;BuildContext&lt;/code&gt; or widgets in a use case, you've gone wrong.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Putting business logic in BLoC&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;BLoC handles state transitions, not business rules. The logic belongs in use cases. BLoC just calls the use case and emits a new state.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Skipping the repository interface&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Some developers implement the repository directly without an abstract class. This makes testing impossible — you can't mock a concrete class cleanly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. One giant feature folder&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Dumping all features into a single &lt;code&gt;lib/screens/&lt;/code&gt; folder defeats the purpose. One folder per feature, with its own data/domain/presentation split.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Not handling &lt;code&gt;Left&lt;/code&gt; (failures)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Using &lt;code&gt;dartz&lt;/code&gt;'s &lt;code&gt;Either&lt;/code&gt; is pointless if you only handle &lt;code&gt;Right&lt;/code&gt;. Always &lt;code&gt;.fold()&lt;/code&gt; and handle both cases.&lt;/p&gt;




&lt;h2&gt;
  
  
  Best Practices
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Test at the use case level.&lt;/strong&gt; Use cases are pure Dart — easy to unit test without Flutter Test infrastructure.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One use case per action.&lt;/strong&gt; &lt;code&gt;LoginUseCase&lt;/code&gt;, &lt;code&gt;LogoutUseCase&lt;/code&gt;, &lt;code&gt;RegisterUseCase&lt;/code&gt; — not a &lt;code&gt;AuthUseCase&lt;/code&gt; that does everything.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use &lt;code&gt;Equatable&lt;/code&gt; on entities and states.&lt;/strong&gt; BLoC won't rebuild on state changes unless equality works correctly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Register BLoCs as &lt;code&gt;Factory&lt;/code&gt;, singletons as &lt;code&gt;LazySingleton&lt;/code&gt;.&lt;/strong&gt; BLoCs hold UI state — they should be created fresh per screen.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keep your &lt;code&gt;ApiClient&lt;/code&gt; in core.&lt;/strong&gt; Don't duplicate Dio setup per feature.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Store the token securely.&lt;/strong&gt; Use &lt;code&gt;flutter_secure_storage&lt;/code&gt; for the Bearer token, not &lt;code&gt;SharedPreferences&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Real-World Use Cases
&lt;/h2&gt;

&lt;p&gt;This architecture isn't academic. It's what powers serious production apps:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SaaS mobile apps&lt;/strong&gt; — Multi-tenant platforms where auth, billing, and user roles need clear separation between layers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;E-commerce apps&lt;/strong&gt; — Product listings, cart, and checkout each live as independent features. One team can work on cart without touching auth.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Admin dashboards&lt;/strong&gt; — Flutter Web admin panels backed by Laravel APIs use this exact structure for scalable role-based access control.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Healthcare apps&lt;/strong&gt; — Where testability and audit trails are non-negotiable, Clean Architecture is the standard.&lt;/p&gt;

&lt;p&gt;Any app that needs to grow, be tested, or be maintained by more than one developer benefits from this structure.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Flutter Clean Architecture isn't about following a textbook pattern for its own sake. It's about building apps that don't become unmanageable.&lt;/p&gt;

&lt;p&gt;With this setup, you get:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A codebase you can test at every layer&lt;/li&gt;
&lt;li&gt;Features that can be built and deployed independently&lt;/li&gt;
&lt;li&gt;A clear contract between your Flutter app and any backend (like Laravel)&lt;/li&gt;
&lt;li&gt;A structure any developer can onboard into quickly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The boilerplate feels like overhead at first. Within weeks on a real project, it saves you hours.&lt;/p&gt;

&lt;p&gt;Start with &lt;code&gt;auth&lt;/code&gt;. Add your next feature using the same pattern. The architecture will carry you.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Found this useful? Follow for more practical Flutter and Laravel content. Clap if it saved you time — it helps others find this guide.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>flutter</category>
      <category>architecture</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>How I Would Get My First Flutter Client in 30 Days (Beginner Plan)</title>
      <dc:creator>Nabeel Krissane</dc:creator>
      <pubDate>Wed, 06 May 2026 19:07:38 +0000</pubDate>
      <link>https://dev.to/nabilkrs/how-i-would-get-my-first-flutter-client-in-30-days-beginner-plan-3jhc</link>
      <guid>https://dev.to/nabilkrs/how-i-would-get-my-first-flutter-client-in-30-days-beginner-plan-3jhc</guid>
      <description>&lt;p&gt;Most Flutter developers don’t fail because of coding.&lt;/p&gt;

&lt;p&gt;They fail because they don’t know how to turn their skills into money.&lt;/p&gt;

&lt;p&gt;You learn Flutter, build a few apps… and then what?&lt;/p&gt;

&lt;p&gt;No clients.&lt;br&gt;
No income.&lt;br&gt;
No direction.&lt;/p&gt;

&lt;p&gt;If I had to start again from zero, here’s exactly what I would do to get my &lt;strong&gt;first Flutter client in 30 days&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The Real Problem&lt;br&gt;
The issue isn’t Flutter.&lt;/p&gt;

&lt;p&gt;It’s this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You don’t know what to offer&lt;/li&gt;
&lt;li&gt;You don’t know where to find clients&lt;/li&gt;
&lt;li&gt;You don’t know how to price your work&lt;/li&gt;
&lt;li&gt;You wait until you're “ready”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And that delays everything.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Stop Trying to Be Perfect
&lt;/h2&gt;

&lt;p&gt;You don’t need to be an expert.&lt;/p&gt;

&lt;p&gt;You need to be useful.&lt;/p&gt;

&lt;p&gt;Start with simple services like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fixing bugs&lt;/li&gt;
&lt;li&gt;Building basic UI screens&lt;/li&gt;
&lt;li&gt;Connecting APIs&lt;/li&gt;
&lt;li&gt;Converting websites into mobile apps&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s enough to get paid.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Create One Simple Portfolio
&lt;/h2&gt;

&lt;p&gt;Don’t overcomplicate this.&lt;/p&gt;

&lt;p&gt;Build 1 solid project:&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A delivery app UI&lt;/li&gt;
&lt;li&gt;A booking app&lt;/li&gt;
&lt;li&gt;A simple e-commerce app&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Upload it to GitHub and record a quick demo.&lt;/p&gt;

&lt;p&gt;That’s your proof.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Price Smart (Not High)
&lt;/h2&gt;

&lt;p&gt;Your first goal is not profit.&lt;/p&gt;

&lt;p&gt;It’s &lt;strong&gt;traction&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Start with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;$100 – $300 small jobs&lt;/li&gt;
&lt;li&gt;$300 – $700 simple apps&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This helps you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Get reviews&lt;/li&gt;
&lt;li&gt;Build confidence&lt;/li&gt;
&lt;li&gt;Understand clients&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can raise prices later.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Find Clients Every Day
&lt;/h2&gt;

&lt;p&gt;This is where most people fail.&lt;/p&gt;

&lt;p&gt;You need daily action.&lt;/p&gt;

&lt;p&gt;Places to find leads:&lt;/p&gt;

&lt;p&gt;Upwork (send 5–10 proposals daily)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Facebook business groups&lt;/li&gt;
&lt;li&gt;LinkedIn outreach&lt;/li&gt;
&lt;li&gt;Local businesses&lt;/li&gt;
&lt;li&gt;Indie hackers / startup founders&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example outreach:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Hi, I saw your business and noticed you don’t have a mobile app. I’m a Flutter developer and can build a simple app to help your customers engage more easily. Let me know if you’re interested.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Keep it simple. No long messages.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Focus on Communication
&lt;/h2&gt;

&lt;p&gt;Clients don’t hire the best developer.&lt;/p&gt;

&lt;p&gt;They hire the one who:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Replies fast&lt;/li&gt;
&lt;li&gt;Understands their needs&lt;/li&gt;
&lt;li&gt;Sounds reliable&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This alone can beat more experienced devs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 6: Avoid These Beginner Mistakes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Waiting to be “ready”&lt;/li&gt;
&lt;li&gt;Building 10 projects but never selling&lt;/li&gt;
&lt;li&gt;Charging too low forever&lt;/li&gt;
&lt;li&gt;Ignoring outreach&lt;/li&gt;
&lt;li&gt;Giving up too early&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Consistency wins.&lt;/p&gt;

&lt;h2&gt;
  
  
  🚀 If You Want a Shortcut
&lt;/h2&gt;

&lt;p&gt;When I was figuring this out, I realized something:&lt;/p&gt;

&lt;p&gt;Most beginners don’t need more tutorials…&lt;br&gt;
They need a clear system to get clients and start earning.&lt;/p&gt;

&lt;p&gt;That’s why I created this:&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://cimoradevtools.gumroad.com/l/flutter-bundle" rel="noopener noreferrer" class="c-link fw-bold flex items-center"&gt;
          &lt;span class="mr-2"&gt;cimoradevtools.gumroad.com&lt;/span&gt;
          

        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;
&lt;br&gt;
The &lt;a href="https://cimoradevtools.gumroad.com/l/flutter-bundle" rel="noopener noreferrer"&gt;Flutter Freelancer Starter Bundle &lt;/a&gt;includes:

&lt;ul&gt;
&lt;li&gt;Client acquisition guide&lt;/li&gt;
&lt;li&gt;Pricing strategy for beginners&lt;/li&gt;
&lt;li&gt;Outreach &amp;amp; proposal templates&lt;/li&gt;
&lt;li&gt;Practical resources to start faster&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s designed to help you skip months of confusion and start taking action immediately.&lt;br&gt;
30-Day Action Plan&lt;/p&gt;

&lt;p&gt;If you follow this, you’ll see results:&lt;/p&gt;

&lt;p&gt;Week 1&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Build 1 project&lt;/li&gt;
&lt;li&gt;Prepare GitHub + demo&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Week 2&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start outreach (5–10 messages/day)&lt;/li&gt;
&lt;li&gt;Apply to jobs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Week 3&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Improve proposals&lt;/li&gt;
&lt;li&gt;Talk to real clients&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Week 4&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Close your first deal&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Final Thought
&lt;/h2&gt;

&lt;p&gt;Your first client won’t come from luck.&lt;/p&gt;

&lt;p&gt;It comes from:&lt;/p&gt;

&lt;p&gt;Showing up daily&lt;br&gt;
Offering simple value&lt;br&gt;
Taking action before you feel ready&lt;/p&gt;

&lt;p&gt;Flutter is just the tool.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Your consistency is what makes you money.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>freelance</category>
      <category>webdev</category>
      <category>career</category>
    </item>
    <item>
      <title>Stopping Fraud Before It Starts: How AI Detects Fake Documents</title>
      <dc:creator>Nabeel Krissane</dc:creator>
      <pubDate>Thu, 02 Oct 2025 19:04:22 +0000</pubDate>
      <link>https://dev.to/nabilkrs/stopping-fraud-before-it-starts-how-ai-detects-fake-documents-38k</link>
      <guid>https://dev.to/nabilkrs/stopping-fraud-before-it-starts-how-ai-detects-fake-documents-38k</guid>
      <description>&lt;p&gt;Every platform that deals with user identity faces the same challenge:&lt;br&gt;&lt;br&gt;
&lt;strong&gt;How do you know if someone is who they say they are?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;From financial apps to online marketplaces, fraudsters constantly try to bypass verification by submitting fake IDs, passports, or altered documents. Traditionally, the process of detecting these fakes required manual review — a slow, expensive, and error-prone method.  &lt;/p&gt;

&lt;p&gt;Today, thanks to AI, we can stop fraud &lt;strong&gt;before it starts&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Growing Problem of Fake Documents
&lt;/h2&gt;

&lt;p&gt;Fake IDs and forged passports aren’t just a problem for governments. Online businesses face them daily:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Marketplaces&lt;/strong&gt; dealing with fake seller accounts.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fintech apps&lt;/strong&gt; preventing fraudulent transactions.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Social platforms&lt;/strong&gt; stopping bots from pretending to be real users.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The cost of letting a fake slip through isn’t just financial — it damages user trust and makes compliance with regulations harder.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why AI Is a Game-Changer
&lt;/h2&gt;

&lt;p&gt;Artificial Intelligence (AI) can process and analyze images far faster and more accurately than humans. When applied to identity verification, AI can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Detect tampered or photoshopped areas.
&lt;/li&gt;
&lt;li&gt;Recognize whether a document matches real government-issued templates.
&lt;/li&gt;
&lt;li&gt;Verify if an image truly contains an ID or passport at all.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of relying on people to spot subtle mistakes, AI does it automatically — and in real-time.&lt;/p&gt;




&lt;h2&gt;
  
  
  How It Works in Practice
&lt;/h2&gt;

&lt;p&gt;Here’s an example using &lt;strong&gt;&lt;a href="https://deepdetect.ai/" rel="noopener noreferrer"&gt;Deep Detect&lt;/a&gt;&lt;/strong&gt;, an AI-powered API that makes document verification simple.&lt;/p&gt;

&lt;p&gt;With just one request, you can check if an uploaded file contains a valid ID or passport:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
bash
curl -X POST "https://api.deepdetect.ai/check" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/uploaded-passport.jpg",
    "service": "id-detection"
  }'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
    </item>
    <item>
      <title>Build an ID Document Detection App in Minutes with Deep Detect</title>
      <dc:creator>Nabeel Krissane</dc:creator>
      <pubDate>Sat, 27 Sep 2025 15:41:51 +0000</pubDate>
      <link>https://dev.to/nabilkrs/build-an-id-document-detection-app-in-minutes-with-deep-detect-34af</link>
      <guid>https://dev.to/nabilkrs/build-an-id-document-detection-app-in-minutes-with-deep-detect-34af</guid>
      <description>&lt;p&gt;Want to automatically detect ID documents (passports, ID cards, driver licenses) in your app? With &lt;a href="https://deepdetect.app" rel="noopener noreferrer"&gt;Deep Detect&lt;/a&gt; you can set up a detection flow in under 15 minutes.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Get your API key &amp;amp; services
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Sign up at &lt;a href="https://deepdetect.app" rel="noopener noreferrer"&gt;deepdetect.app&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;You’ll get an API key.&lt;/li&gt;
&lt;li&gt;To list available detection services (like ID documents, faces, license plates, etc.), call the services endpoint:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl --location 'https://deepdetect.app/api/get-services' \
  --header 'dd-api-key: YOUR_API_KEY'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This returns service codes you’ll use when analyzing images.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Call the analyze-image endpoint
&lt;/h2&gt;

&lt;p&gt;Basic request (replace &lt;code&gt;SERVICE-CODE&lt;/code&gt; with your ID detection service code):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl --location 'https://deepdetect.app/api/analyze-image' \
  --header 'dd-api-key: YOUR_API_KEY' \
  --form 'image=@"/path/to/file.jpg"' \
  --form 'action="SERVICE-CODE"'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The API responds with predictions + confidence scores. You can decide thresholds (e.g., passport confidence &amp;gt; 0.7).&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Add a tiny proxy server
&lt;/h2&gt;

&lt;p&gt;Never expose your API key in frontend code. Quick Node.js proxy example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app.post('/api/detect-id', upload.single('image'), async (req, res) =&amp;gt; {
  const form = new FormData();
  form.append('image', fs.createReadStream(req.file.path));
  form.append('action', process.env.DD_SERVICE);

  const ddRes = await axios.post('https://deepdetect.app/api/analyze-image', form, {
    headers: { 'dd-api-key': process.env.DD_API_KEY, ...form.getHeaders() },
  });

  res.json(ddRes.data);
});

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

&lt;/div&gt;



&lt;p&gt;Frontend just uploads to &lt;code&gt;/api/detect-id&lt;/code&gt; and shows the result.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. That’s it 🎉
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;List services with &lt;code&gt;/api/services&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Detect ID documents with &lt;code&gt;/api/analyze-image&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Wrap it in a small backend proxy.&lt;/li&gt;
&lt;li&gt;Use predictions + confidence scores to flag or process ID documents in your app.
In minutes, you’ve got a working &lt;strong&gt;ID document detection app&lt;/strong&gt; powered by Deep Detect.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>api</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to Detect NSFW Images in Your Platform Using Deep Detect API</title>
      <dc:creator>Nabeel Krissane</dc:creator>
      <pubDate>Sun, 22 Jun 2025 15:46:30 +0000</pubDate>
      <link>https://dev.to/nabilkrs/how-to-detect-nsfw-images-in-your-platform-using-deep-detect-api-1l0g</link>
      <guid>https://dev.to/nabilkrs/how-to-detect-nsfw-images-in-your-platform-using-deep-detect-api-1l0g</guid>
      <description>&lt;p&gt;Ensuring a safe and user-friendly environment on your platform is more critical than ever, especially with the rise of user-generated content across social media, forums, and e-commerce sites. NSFW (Not Safe For Work) images—encompassing explicit adult content, nudity, or sexual activity—can alienate users, damage your brand reputation, and even lead to legal challenges. Fortunately, the &lt;strong&gt;Deep Detect API&lt;/strong&gt; offers a robust solution to detect and filter such content seamlessly. In this post, we’ll dive into how you can integrate this powerful tool into your platform to enhance safety and compliance.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Deep Detect?
&lt;/h2&gt;

&lt;p&gt;Deep Detect is a state-of-the-art SaaS platform designed to provide advanced image analysis services tailored for content moderation, security, and compliance. One of its key offerings is the NSFW detection service, accessible via the service code &lt;code&gt;XeAkkf&lt;/code&gt;. This feature leverages cutting-edge AI to identify inappropriate content with high accuracy, making it an essential tool for platforms aiming to maintain strict moderation policies. Beyond NSFW detection, Deep Detect supports a wide range of services, from identifying weapons and hate symbols to detecting AI-generated images, offering a comprehensive moderation suite.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why NSFW Detection Matters
&lt;/h2&gt;

&lt;p&gt;In today’s digital landscape, user trust is paramount. Unmoderated NSFW content can drive away loyal users, attract negative attention, and result in regulatory fines, especially under laws like the EU’s Digital Services Act. Manually reviewing images is time-consuming and impractical for scaling platforms. The Deep Detect API automates this process, allowing you to focus on growth while ensuring a safe environment for your community.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started with Deep Detect
&lt;/h2&gt;

&lt;p&gt;To harness the power of Deep Detect, you’ll need to sign up at &lt;a href="https://deepdetect.app" rel="noopener noreferrer"&gt;deepdetect.app&lt;/a&gt; to obtain an API key. This key unlocks access to all available services, including NSFW detection. The platform offers a flexible pay-as-you-go pricing model, making it accessible for startups and established businesses alike. Once you have your API key, you’re ready to integrate the service into your application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Python Integration Example
&lt;/h2&gt;

&lt;p&gt;Below is a detailed Python script using the &lt;code&gt;requests&lt;/code&gt; library to detect NSFW images with the Deep Detect API. Replace &lt;code&gt;XXX&lt;/code&gt; with your actual API key and update the &lt;code&gt;file_path&lt;/code&gt; to point to your image file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;

&lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://deepdetect.app/api/analyze-image&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;api_key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;XXX&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;file_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/path/to/file&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;rb&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;image_file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;files&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;image&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;image_file&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;action&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;XeAkkf&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;headers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Accept&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;application/json&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;dd-api-key&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;files&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;files&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;NSFW Detection Result:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;is_nsfw&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Image contains NSFW content. Take action!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Image is safe.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Error:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  How to Use the Script
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Install Dependencies&lt;/strong&gt;: Ensure you have &lt;code&gt;requests&lt;/code&gt; installed (&lt;code&gt;pip install requests&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Update Credentials&lt;/strong&gt;: Insert your API key and the path to the image you want to analyze.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Run the Script&lt;/strong&gt;: Execute it to get a JSON response indicating NSFW status.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Act on Results&lt;/strong&gt;: Use the output to flag or remove inappropriate content in your platform.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  How the Deep Detect API Works
&lt;/h2&gt;

&lt;p&gt;The process is straightforward:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Upload the Image&lt;/strong&gt;: The script sends the image file to the API endpoint.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Specify the Action&lt;/strong&gt;: The &lt;code&gt;action&lt;/code&gt; parameter set to &lt;code&gt;XeAkkf&lt;/code&gt; triggers the NSFW detection service.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Receive the Response&lt;/strong&gt;: The API returns a JSON object with details, including a boolean indicating NSFW content presence.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automate Moderation&lt;/strong&gt;: Integrate the result into your workflow to block or review flagged images.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Benefits of Using Deep Detect
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;High Accuracy&lt;/strong&gt;: Powered by advanced AI, it minimizes false positives and negatives.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ease of Integration&lt;/strong&gt;: The API is developer-friendly and works with any programming language.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalability&lt;/strong&gt;: The pay-as-you-go plan adapts to your usage, perfect for growing platforms.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Comprehensive Coverage&lt;/strong&gt;: Beyond NSFW, detect violence (&lt;code&gt;5fK43A&lt;/code&gt;), hate symbols (&lt;code&gt;XTv6pq&lt;/code&gt;), or copyrighted content (&lt;code&gt;ZEuGTB&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Time-Saving&lt;/strong&gt;: Automates what would otherwise require extensive manual review.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Expanding Your Moderation Strategy
&lt;/h2&gt;

&lt;p&gt;While NSFW detection is a great starting point, consider combining it with other Deep Detect services for a holistic approach. For instance:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;5fK43A&lt;/code&gt; to detect violence or gore.&lt;/li&gt;
&lt;li&gt;Employ &lt;code&gt;XTv6pq&lt;/code&gt; to identify hate symbols.&lt;/li&gt;
&lt;li&gt;Leverage &lt;code&gt;ZEuGTB&lt;/code&gt; to protect against copyrighted material.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This multi-layered moderation ensures your platform remains safe and compliant across all content types.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next Steps
&lt;/h2&gt;

&lt;p&gt;Integrate the Deep Detect API into your platform’s content moderation pipeline today. Start with a small test using the provided script, then scale to real-time analysis as needed. Visit &lt;a href="https://deepdetect.app" rel="noopener noreferrer"&gt;deepdetect.app&lt;/a&gt; to sign up for a free trial and explore the full range of features. Join a growing community of developers and businesses leveraging Deep Detect to create safer digital spaces.&lt;/p&gt;

&lt;p&gt;Happy coding, and let’s build a safer internet together with Deep Detect!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to Host a Flutter Web App on Microsoft Azure</title>
      <dc:creator>Nabeel Krissane</dc:creator>
      <pubDate>Wed, 22 Mar 2023 09:08:12 +0000</pubDate>
      <link>https://dev.to/nabilkrs/how-to-host-a-flutter-web-app-on-microsoft-azure-2hc6</link>
      <guid>https://dev.to/nabilkrs/how-to-host-a-flutter-web-app-on-microsoft-azure-2hc6</guid>
      <description>&lt;p&gt;Flutter has become an increasingly popular framework for developing cross-platform mobile applications. In addition to mobile apps, Flutter also supports web app development, enabling developers to create responsive and engaging web experiences. Microsoft Azure is a cloud computing platform that provides various services for hosting, deploying, and managing web applications. In this article, we'll guide you through the process of hosting a Flutter web app on Microsoft Azure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before diving into the process, make sure you have the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A Flutter web app: Create a new Flutter web app or use an existing one.&lt;/li&gt;
&lt;li&gt;Microsoft Azure account: Sign up for a free trial or use your existing account.&lt;/li&gt;
&lt;li&gt;Azure CLI: Install the Azure Command-Line Interface (CLI) on your machine.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Build the Flutter Web App
&lt;/h2&gt;

&lt;p&gt;To deploy the Flutter web app, first, you need to build it for production. Open a terminal and navigate to the root directory of your Flutter project. Run the following command:&lt;br&gt;
&lt;code&gt;flutter build web&lt;/code&gt;&lt;br&gt;
This command will generate the necessary files for your web app in the build/web directory.&lt;/p&gt;

&lt;h2&gt;
  
  
  Set Up a Storage Account on Azure
&lt;/h2&gt;

&lt;p&gt;A Storage Account in Azure is used to store and manage your web app's files. To create a new storage account, follow these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Sign in to the &lt;a href="https://portal.azure.com"&gt;Azure portal&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Click on "Create a resource" in the left sidebar.&lt;/li&gt;
&lt;li&gt;Search for "Storage Account" and click "Create."&lt;/li&gt;
&lt;li&gt;Fill in the required fields, such as subscription, resource group, account name, and location. Click "Review + create" and then "Create" to finalize.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Enable Static Website Hosting
&lt;/h2&gt;

&lt;p&gt;Once your storage account is created, enable static website hosting:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Navigate to your storage account in the Azure portal.&lt;/li&gt;
&lt;li&gt;Click on "Static website" under the "Settings" section.&lt;/li&gt;
&lt;li&gt;Set "Static website" to "Enabled.".&lt;/li&gt;
&lt;li&gt;Set "Index document name" to "index.html" and "Error document path" to "404.html."&lt;/li&gt;
&lt;li&gt;Click "Save."&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Deploy Your Flutter Web App
&lt;/h2&gt;

&lt;p&gt;Now that your storage account is set up and static website hosting is enabled, you can deploy your Flutter web app. First, sign in to Azure CLI using:&lt;br&gt;
&lt;code&gt;az login&lt;/code&gt;&lt;br&gt;
Once logged in, navigate to the &lt;code&gt;build/web&lt;/code&gt; directory of your Flutter project and run the following command:&lt;br&gt;
&lt;code&gt;az storage blob upload-batch -s . -d '$web' --account-name &amp;lt;YourStorageAccountName&amp;gt; --account-key &amp;lt;YourStorageAccountKey&amp;gt;&lt;/code&gt;&lt;br&gt;
Replace &lt;code&gt;&amp;lt;YourStorageAccountName&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;YourStorageAccountKey&amp;gt;&lt;/code&gt; with the appropriate values from your storage account. You can find these in the "Access keys" section of your storage account settings in the Azure portal.&lt;/p&gt;

&lt;h2&gt;
  
  
  Access Your Flutter Web App
&lt;/h2&gt;

&lt;p&gt;After deploying your web app, you can access it using the provided URL. In the Azure portal, navigate to your storage account and click on "Static website" under the "Settings" section. You'll see the "Primary endpoint" URL. Open this URL in a web browser to see your Flutter web app in action.&lt;br&gt;
And voila your web app is hosted on Microsoft Azure!&lt;/p&gt;

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