<?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: Alhiane Lahcen</title>
    <description>The latest articles on DEV Community by Alhiane Lahcen (@alhiane).</description>
    <link>https://dev.to/alhiane</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%2F303342%2F8c27c232-c4fb-4c26-bce3-4ddfabfd61d4.jpg</url>
      <title>DEV Community: Alhiane Lahcen</title>
      <link>https://dev.to/alhiane</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/alhiane"/>
    <language>en</language>
    <item>
      <title>Disabling WordPress plugins for one browser only, on a live site</title>
      <dc:creator>Alhiane Lahcen</dc:creator>
      <pubDate>Wed, 11 Nov 2026 12:00:00 +0000</pubDate>
      <link>https://dev.to/alhiane/disabling-wordpress-plugins-for-one-browser-only-on-a-live-site-4n32</link>
      <guid>https://dev.to/alhiane/disabling-wordpress-plugins-for-one-browser-only-on-a-live-site-4n32</guid>
      <description>&lt;p&gt;"Deactivate all plugins" is the first step in almost every WordPress troubleshooting guide. On a live store it is also the step that breaks checkout for every real customer while you test.&lt;/p&gt;

&lt;p&gt;There is another way: turn plugins off &lt;strong&gt;only for your own browser&lt;/strong&gt;. Visitors, search engines and other admins keep seeing the normal site. Nothing in the database changes.&lt;/p&gt;

&lt;p&gt;This post shows how that works, with a small must-use plugin you can read in five minutes, and the one trap that can quietly wipe a site's active plugin list.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where WordPress decides which plugins load
&lt;/h2&gt;

&lt;p&gt;On every request, WordPress reads the &lt;code&gt;active_plugins&lt;/code&gt; option and loads each plugin in that list. That read goes through &lt;code&gt;get_option()&lt;/code&gt;, and every &lt;code&gt;get_option()&lt;/code&gt; call runs the filter &lt;code&gt;option_{$name}&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So if code runs &lt;strong&gt;before&lt;/strong&gt; normal plugins load, it can change the list for this one request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nf"&gt;add_filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'option_active_plugins'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$plugins&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="nb"&gt;array_diff&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$plugins&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'some-plugin/some-plugin.php'&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;Must-use plugins (files in &lt;code&gt;wp-content/mu-plugins/&lt;/code&gt;) load before normal plugins, so they are the right place for this filter.&lt;/p&gt;

&lt;p&gt;On multisite, network-activated plugins live in a different option, &lt;code&gt;active_sitewide_plugins&lt;/code&gt;, filtered with &lt;code&gt;site_option_active_sitewide_plugins&lt;/code&gt;. Handle both if you support multisite.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scoping it to one browser
&lt;/h2&gt;

&lt;p&gt;The filter above applies to everyone. We only want it for one person.&lt;/p&gt;

&lt;p&gt;The obvious idea is "only when the current user is an admin". That does not work here: when must-use plugins run, WordPress has not loaded the user functions yet (&lt;code&gt;pluggable.php&lt;/code&gt; loads &lt;strong&gt;after&lt;/strong&gt; plugins). You cannot call &lt;code&gt;is_user_logged_in()&lt;/code&gt; this early.&lt;/p&gt;

&lt;p&gt;So use a cookie instead:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;When the admin starts a test session (from a normal admin page, where you &lt;strong&gt;can&lt;/strong&gt; check capabilities and a nonce), create a random token.&lt;/li&gt;
&lt;li&gt;Store a hash of the token, an expiry time and the list of plugins to skip in an option.&lt;/li&gt;
&lt;li&gt;Send the raw token to the admin's browser as a cookie.&lt;/li&gt;
&lt;li&gt;In the must-use plugin, compare the cookie's hash to the stored hash. Only filter when they match.
&lt;/li&gt;
&lt;/ol&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="cd"&gt;/**
 * Plugin Name: One-browser plugin filter (demo)
 * Description: Skips selected plugins for one browser session only.
 */&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="nb"&gt;defined&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'ABSPATH'&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;exit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="no"&gt;OBPF_COOKIE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'obpf_session'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="no"&gt;OBPF_OPTION&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'obpf_session'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;obpf_current_session&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="nv"&gt;$session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="nv"&gt;$checked&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="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$checked&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="nv"&gt;$session&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nv"&gt;$checked&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;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="k"&gt;empty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$_COOKIE&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="no"&gt;OBPF_COOKIE&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;return&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="c1"&gt;// Shape: [ 'token_hash' =&amp;gt; string, 'expires' =&amp;gt; int, 'disabled' =&amp;gt; string[] ]&lt;/span&gt;
    &lt;span class="nv"&gt;$stored&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_option&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="no"&gt;OBPF_OPTION&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="nb"&gt;is_array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$stored&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;time&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="n"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$stored&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'expires'&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="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="nv"&gt;$token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nf"&gt;wp_unslash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$_COOKIE&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="no"&gt;OBPF_COOKIE&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="o"&gt;!&lt;/span&gt; &lt;span class="nb"&gt;hash_equals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$stored&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'token_hash'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nb"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'sha256'&lt;/span&gt;&lt;span class="p"&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;span class="k"&gt;return&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="nv"&gt;$session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$stored&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$session&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;add_filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'option_active_plugins'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$plugins&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;obpf_current_session&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;$session&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="nv"&gt;$plugins&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="nb"&gt;array_values&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nb"&gt;array_diff&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;array&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$plugins&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;array&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$session&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'disabled'&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;Why a hash and &lt;code&gt;hash_equals()&lt;/code&gt;? If the database leaks, the stored value alone is not enough to start someone else's session, and the comparison does not leak timing information.&lt;/p&gt;

&lt;p&gt;Anyone without the cookie gets the unfiltered list. That includes visitors, crawlers, and other admins on their own browsers.&lt;/p&gt;

&lt;h2&gt;
  
  
  The trap: saving the filtered list
&lt;/h2&gt;

&lt;p&gt;This is the part that bites people.&lt;/p&gt;

&lt;p&gt;While your session is active, &lt;code&gt;get_option( 'active_plugins' )&lt;/code&gt; returns the &lt;strong&gt;shortened&lt;/strong&gt; list. Now imagine you activate or deactivate any plugin during the session. WordPress reads the active list (shortened), changes it, and saves it back with &lt;code&gt;update_option()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The plugins you were "only hiding" are now really deactivated, for everyone.&lt;/p&gt;

&lt;p&gt;Ways to avoid it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Block plugin changes during a session.&lt;/strong&gt; Disable activate/deactivate/update/delete actions on the Plugins screen while the cookie is valid, and show a notice that says why.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Or don't filter on those requests.&lt;/strong&gt; Skip the filter on &lt;code&gt;plugins.php&lt;/code&gt; and &lt;code&gt;update.php&lt;/code&gt; actions. This is harder to get fully right, because other code can also write the option.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test it.&lt;/strong&gt; Start a session, try to activate a plugin, then check the real option from a second browser or with WP-CLI: &lt;code&gt;wp option get active_plugins&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Caching
&lt;/h2&gt;

&lt;p&gt;Page caches are the other place this can go wrong.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The admin is logged in, and most page caches skip logged-in users, so the admin usually sees uncached pages. Check your cache does this, or add the session cookie to its bypass list.&lt;/li&gt;
&lt;li&gt;The bigger risk is the reverse: a filtered page (missing a plugin's output) getting cached and served to visitors. A cookie bypass rule prevents this.&lt;/li&gt;
&lt;li&gt;The persistent object cache is safe. The filter runs &lt;strong&gt;after&lt;/strong&gt; the value is read, so the cached &lt;code&gt;active_plugins&lt;/code&gt; value itself is never changed.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Safety exits
&lt;/h2&gt;

&lt;p&gt;If you skip the wrong plugin, you can lock yourself out of wp-admin. For example, a security or login plugin, or a plugin that another plugin depends on. You need ways out that do not depend on the admin area working:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A clear Exit button&lt;/strong&gt; in the admin bar that deletes the option and the cookie.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;An emergency link&lt;/strong&gt; that works when you are logged out. Because the must-use plugin runs before authentication, it can check for a secret URL parameter and end the session. Show the link to the admin when the session starts, so they can copy it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;An expiry time.&lt;/strong&gt; Sessions should end by themselves. Pair a short idle timeout with a hard maximum.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Last resort:&lt;/strong&gt; delete the session option with WP-CLI or phpMyAdmin, or rename the must-use plugin file over FTP.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What this method can't test
&lt;/h2&gt;

&lt;p&gt;Because it works by filtering the plugin list, some things stay out of reach:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The theme.&lt;/strong&gt; It loads through a different path.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Must-use plugins and drop-ins&lt;/strong&gt; (&lt;code&gt;object-cache.php&lt;/code&gt;, &lt;code&gt;advanced-cache.php&lt;/code&gt;, &lt;code&gt;db.php&lt;/code&gt;). They load before or outside the normal plugin list.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Server settings&lt;/strong&gt;: PHP version, memory limit, &lt;code&gt;.htaccess&lt;/code&gt; or nginx rules.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If a problem survives with every normal plugin skipped, look at those next.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tools that do this for you
&lt;/h2&gt;

&lt;p&gt;You don't have to write this yourself:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://wordpress.org/plugins/health-check/" rel="noopener noreferrer"&gt;Health Check &amp;amp; Troubleshooting&lt;/a&gt;&lt;/strong&gt;: its troubleshooting mode turns off plugins for your session only. You choose which ones to turn back on.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://wordpress.org/plugins/culprit-finder/" rel="noopener noreferrer"&gt;Culprit Finder&lt;/a&gt;&lt;/strong&gt;: a free, GPL plugin I built (disclosure: I'm the author). It switches plugins off only for your own logged-in browser and never changes the active plugin list. It then runs a binary search to find the plugin causing the problem, or the two plugins that only break together. It has an Exit button, an emergency link that works logged out, and it stops by itself after 60 idle minutes (3 hours max). No account, no tracking, no external requests.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;option_active_plugins&lt;/code&gt; in a must-use plugin lets you change the plugin list for one request.&lt;/li&gt;
&lt;li&gt;Scope it with a hashed cookie token, not a user check. User functions aren't loaded yet.&lt;/li&gt;
&lt;li&gt;Never let the filtered list be saved back. Block plugin changes during a session.&lt;/li&gt;
&lt;li&gt;Make sure page caches never store or serve the filtered version.&lt;/li&gt;
&lt;li&gt;Build exits that work even when wp-admin doesn't.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Have you used a per-session approach on a production site? I'd like to hear what broke, or what you'd add to the safety list.&lt;/p&gt;

</description>
      <category>wordpress</category>
      <category>php</category>
      <category>debugging</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Writing a WordPress plugin bug report that support teams can actually act on</title>
      <dc:creator>Alhiane Lahcen</dc:creator>
      <pubDate>Mon, 09 Nov 2026 20:46:49 +0000</pubDate>
      <link>https://dev.to/alhiane/writing-a-wordpress-plugin-bug-report-that-support-teams-can-actually-act-on-3hhl</link>
      <guid>https://dev.to/alhiane/writing-a-wordpress-plugin-bug-report-that-support-teams-can-actually-act-on-3hhl</guid>
      <description>&lt;p&gt;If you have ever posted in a WordPress plugin support forum, you know the first reply by heart:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Can you share your System Info, the steps to reproduce, and confirm the issue happens with only our plugin active?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That reply costs you a day, sometimes three. The support person isn't stalling. They can't do anything with "checkout is broken since the update, please fix ASAP." They need to see the bug happen on their own test site, and your report is the only map they have.&lt;/p&gt;

&lt;p&gt;I build and support a WordPress plugin, and I read a lot of these threads. The ones that get fixed fast all have the same shape. Here it is.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. One sentence: what you expected vs. what happened
&lt;/h2&gt;

&lt;p&gt;Not "it doesn't work." Two halves:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Expected:&lt;/strong&gt; "Clicking &lt;em&gt;Place order&lt;/em&gt; with Stripe should go to the thank-you page."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Actual:&lt;/strong&gt; "The spinner runs for about 10 seconds, then 'There was an error processing your order' appears. No order is created."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Copy any error text exactly. Screenshots are good. The exact text is better, because people can search it.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Steps to reproduce, from a clean start
&lt;/h2&gt;

&lt;p&gt;Write them like a recipe someone else will follow on a fresh install:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Add any simple product to the cart.&lt;/li&gt;
&lt;li&gt;Go to &lt;code&gt;/checkout/&lt;/code&gt; as a logged-out visitor.&lt;/li&gt;
&lt;li&gt;Choose Stripe, use test card &lt;code&gt;4242 4242 4242 4242&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Click &lt;em&gt;Place order&lt;/em&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Then add one line: &lt;strong&gt;does it happen every time, or sometimes?&lt;/strong&gt; "3 out of 5 tries" is a useful fact. Bugs that happen "sometimes" are often caching, cron or race conditions, and the developer will look in a different place.&lt;/p&gt;

&lt;p&gt;Also note &lt;strong&gt;who&lt;/strong&gt; sees it: logged-out visitors only? Admins only? One browser? That one detail can cut the search in half.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Versions, all of them
&lt;/h2&gt;

&lt;p&gt;The developer will try to rebuild your setup. Give them the numbers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;WordPress version&lt;/li&gt;
&lt;li&gt;PHP version&lt;/li&gt;
&lt;li&gt;The plugin's version (and the version where it last worked, if you know it)&lt;/li&gt;
&lt;li&gt;Active theme and its version&lt;/li&gt;
&lt;li&gt;Hosting type if relevant (managed host, object cache, CDN)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You don't have to type this. &lt;strong&gt;Tools → Site Health → Info → Copy site info to clipboard&lt;/strong&gt; gives you all of it. Paste it inside a collapsible block or a code block if the forum supports it. Remove anything private first (the copy is plain text, so read it before posting).&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Prove it's this plugin (or name the pair)
&lt;/h2&gt;

&lt;p&gt;This is the part most reports skip, and it's the one that matters most.&lt;/p&gt;

&lt;p&gt;Every plugin developer has spent hours on a bug that turned out to come from a different plugin. So the first thing they will ask is: &lt;strong&gt;does it still happen when only our plugin (plus WooCommerce, if it's a Woo extension) is active, with a default theme?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you can answer that before they ask, your thread jumps the queue. There are a few ways to get the answer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;On a staging copy:&lt;/strong&gt; deactivate everything except the plugin in question, switch to a default theme like Twenty Twenty-Five, test. Then turn plugins back on in halves until the bug returns. Halving is much faster than one by one: 30 plugins take about 5 to 7 rounds, not 30.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;On the live site, without breaking it for visitors:&lt;/strong&gt; the Health Check &amp;amp; Troubleshooting plugin can disable plugins for your logged-in session only.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;With a conflict tool:&lt;/strong&gt; I built &lt;a href="https://wordpress.org/plugins/culprit-finder/" rel="noopener noreferrer"&gt;Culprit Finder&lt;/a&gt; for exactly this step (disclosure: I'm the author). It runs the halving for your browser only, asks "is the problem still there?" after each round, and at the end gives you a plain-text report to paste into the support thread. It's free and open source.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Whatever method you use, the answer usually lands in one of three buckets, and each one is worth stating clearly:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;What you found&lt;/th&gt;
&lt;th&gt;What to write&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Happens with only this plugin active&lt;/td&gt;
&lt;td&gt;"Reproduces with only X active and Twenty Twenty-Five." The developer now owns it.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Only happens with one other plugin also active&lt;/td&gt;
&lt;td&gt;"Only happens when X and Y are both active. Either one alone is fine." This is a conflict. Post it to &lt;strong&gt;both&lt;/strong&gt; plugins' forums and link the threads.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Disappears with a default theme&lt;/td&gt;
&lt;td&gt;"Goes away with Twenty Twenty-Five." Now it's a theme issue (or theme + plugin).&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;That middle row is the one people miss. Two plugins can each work fine alone and break only together, for example both loading a different version of the same JavaScript library, or both hooking the same filter at the same priority. If you only ever test "all on" vs. "one off," you will never see it.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. The error log, trimmed
&lt;/h2&gt;

&lt;p&gt;If there's a PHP error, it's the single most useful thing you can send. Turn on logging in &lt;code&gt;wp-config.php&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nb"&gt;define&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'WP_DEBUG'&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="nb"&gt;define&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'WP_DEBUG_LOG'&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="nb"&gt;define&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'WP_DEBUG_DISPLAY'&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Reproduce the bug once, then open &lt;code&gt;wp-content/debug.log&lt;/code&gt;. Post only the lines that appeared at the time of your test, usually a &lt;code&gt;PHP Fatal error&lt;/code&gt; or &lt;code&gt;Uncaught&lt;/code&gt; line plus the stack trace under it. Not the whole 4 MB file.&lt;/p&gt;

&lt;p&gt;For front-end bugs (buttons that do nothing, endless spinners), open the browser console (F12 → Console) and the Network tab, reproduce, and copy any red errors. A failed &lt;code&gt;admin-ajax.php&lt;/code&gt; or &lt;code&gt;/wp-json/&lt;/code&gt; request with its response body is gold.&lt;/p&gt;

&lt;p&gt;Turn debug mode off again when you're done.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. What you already tried
&lt;/h2&gt;

&lt;p&gt;A short list saves a round trip:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cleared site cache and CDN cache&lt;/li&gt;
&lt;li&gt;Re-saved permalinks&lt;/li&gt;
&lt;li&gt;Tested in a private window&lt;/li&gt;
&lt;li&gt;Rolled the plugin back to 4.2.1 → works; 4.3.0 → broken&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The last line is the best clue you can give a developer. It points straight at one release.&lt;/p&gt;

&lt;h2&gt;
  
  
  A template you can paste
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;**Expected:** 
**Actual:** (exact error text)

**Steps to reproduce:**
1.
2.
3.
Happens: every time / sometimes (x of y tries)
Who sees it: visitors / logged-in / admins / one browser

**Isolation:**
- With only [this plugin] (+ WooCommerce) and a default theme: yes / no
- Conflicts with: [other plugin + version], or "none found"

**Versions:** WP __ · PHP __ · plugin __ (last working __) · theme __
(Site Health info attached below)

**Errors:** (debug.log lines / console errors)

**Already tried:**
- 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why this works
&lt;/h2&gt;

&lt;p&gt;Support teams triage. A thread with a clear expected/actual, clean steps, versions, and an isolation result can be reproduced in ten minutes, so it gets picked up first. A thread that says "broken, urgent" waits for a back-and-forth that can take days.&lt;/p&gt;

&lt;p&gt;You're not doing their job for them. You're giving them the one thing only you have: your site.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;If you maintain a plugin: consider pinning a version of this template in your support forum. The reports you get back will be better on day one.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>wordpress</category>
      <category>php</category>
      <category>debugging</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Finding a broken WordPress plugin in 7 questions instead of 30 toggles</title>
      <dc:creator>Alhiane Lahcen</dc:creator>
      <pubDate>Wed, 04 Nov 2026 12:24:35 +0000</pubDate>
      <link>https://dev.to/alhiane/finding-a-broken-wordpress-plugin-in-7-questions-instead-of-30-toggles-2fj6</link>
      <guid>https://dev.to/alhiane/finding-a-broken-wordpress-plugin-in-7-questions-instead-of-30-toggles-2fj6</guid>
      <description>&lt;p&gt;Every WordPress support thread ends up at the same advice: "Deactivate all your plugins, then turn them back on one by one until it breaks."&lt;/p&gt;

&lt;p&gt;It works. It is also slow, and on a live site it is risky. With 30 plugins you can be toggling for an hour while real visitors watch the site break and un-break. And there is one kind of bug it can miss completely.&lt;/p&gt;

&lt;p&gt;This post covers a faster method you can do by hand, and the case that one-by-one testing gets wrong.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem with one-by-one
&lt;/h2&gt;

&lt;p&gt;One-by-one testing is a linear search. With 30 plugins, the worst case is 30 rounds of "turn one on, reload, check."&lt;/p&gt;

&lt;p&gt;Each round is not just a click. You reload the page, maybe clear a cache, maybe go through checkout again. Multiply that by 30.&lt;/p&gt;

&lt;h2&gt;
  
  
  Halve the suspects instead
&lt;/h2&gt;

&lt;p&gt;Binary search is the same idea as the "guess my number" game. Every test should cut the list of suspects in half.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Write down your active plugins. Make a backup first.&lt;/li&gt;
&lt;li&gt;Turn off &lt;strong&gt;half&lt;/strong&gt; of them.&lt;/li&gt;
&lt;li&gt;Check the problem.

&lt;ul&gt;
&lt;li&gt;Problem gone? The culprit is in the half you turned off.&lt;/li&gt;
&lt;li&gt;Problem still there? The culprit is in the half that is still on.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Throw away the innocent half. Repeat with the suspects that are left.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;With 30 plugins, the suspects go 30 → 15 → 8 → 4 → 2 → 1. That is about five tests instead of up to thirty.&lt;/p&gt;

&lt;p&gt;A few practical tips:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Keep a written list.&lt;/strong&gt; After the third round it is very easy to lose track of which plugins are "on" for which reason.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test the same thing every time.&lt;/strong&gt; Same page, same steps, same logged-in or logged-out state. If the bug only shows at checkout, go through checkout every round.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clear caches between rounds.&lt;/strong&gt; A page cache can show you the old result and send you down the wrong half.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Leave dependencies together.&lt;/strong&gt; If an add-on needs its parent plugin (a WooCommerce extension needs WooCommerce), turn them off and on as a group.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The case one-by-one testing misses
&lt;/h2&gt;

&lt;p&gt;Sometimes no single plugin is broken. Plugin A works alone. Plugin B works alone. Turn both on and checkout fails.&lt;/p&gt;

&lt;p&gt;Look at what one-by-one testing does here. You turn everything off, then turn plugins back on one at a time. The site only breaks when the &lt;em&gt;second&lt;/em&gt; plugin of the pair comes back. So you blame that plugin, report a bug to its author, and they cannot reproduce it, because it only fails next to the other one.&lt;/p&gt;

&lt;p&gt;Plain binary search can trip on this too. Split the plugins in half and the pair may land on different sides. Then &lt;strong&gt;both halves work on their own&lt;/strong&gt;, but the full set breaks. That result is the clue.&lt;/p&gt;

&lt;p&gt;When you see "half A alone works, half B alone works, all together breaks," you know the culprit is a pair split across the two halves. To find it:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Keep half A fully on. Binary-search half B (turn half of B off, check, and so on). The plugin in B that brings the problem back is the first member of the pair.&lt;/li&gt;
&lt;li&gt;Now keep that one plugin from B on. Binary-search half A the same way. That finds the second member.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It is still a handful of tests, and you end up with the real answer: "A and B conflict," not "B is broken."&lt;/p&gt;

&lt;h2&gt;
  
  
  Doing this on a live site
&lt;/h2&gt;

&lt;p&gt;All of the above assumes you can switch plugins off. On a real store, every round means customers might see a broken checkout, missing features, or a broken layout.&lt;/p&gt;

&lt;p&gt;The usual options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A staging copy.&lt;/strong&gt; The safest choice, if you have one and it really matches production (same PHP version, same plugin versions).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Health Check &amp;amp; Troubleshooting plugin.&lt;/strong&gt; Its troubleshooting mode disables plugins only for your session, so visitors keep the normal site. You still choose which plugins to enable yourself.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Recovery mode.&lt;/strong&gt; For fatal errors, WordPress emails the admin a link to log in with the broken plugin paused.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I built a small open-source plugin, &lt;a href="https://wordpress.org/plugins/culprit-finder/" rel="noopener noreferrer"&gt;Culprit Finder&lt;/a&gt;, that runs the binary search above for you (disclosure: I'm the author). It switches plugins off only for your own logged-in browser, so visitors, search engines and other admins keep seeing the full site, and the active plugin list never changes. You answer "is the problem still there?" and it picks the next half. For a 30-plugin site that is usually around 7 answers, and it also catches two-plugin conflicts like the one above. When it is done, it gives you a plain-text report you can paste into a plugin's support forum.&lt;/p&gt;

&lt;p&gt;It has exits in case something goes wrong: an Exit button, an emergency link that works even when you are logged out, and it stops by itself after 60 idle minutes (3 hours max). It is free, GPL, and makes no external requests. It cannot test your theme, must-use plugins, drop-ins, or server settings, so if the problem survives with every plugin off, look there next.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Don't toggle 30 plugins one at a time. Halve the suspects each round.&lt;/li&gt;
&lt;li&gt;If both halves work alone but the full set breaks, you have a two-plugin conflict. Search one half while keeping the other on.&lt;/li&gt;
&lt;li&gt;Report conflicts as pairs. "B breaks only when A is active" is a bug report a developer can act on.&lt;/li&gt;
&lt;li&gt;On a live site, test in a way that does not change what visitors see.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What is the worst plugin conflict you have had to track down? I'm collecting real cases for the next post.&lt;/p&gt;

</description>
      <category>wordpress</category>
      <category>php</category>
      <category>debugging</category>
      <category>opensource</category>
    </item>
    <item>
      <title>ValidatorKit: Simplify iOS Data Validation with Swift</title>
      <dc:creator>Alhiane Lahcen</dc:creator>
      <pubDate>Wed, 25 Sep 2024 12:56:01 +0000</pubDate>
      <link>https://dev.to/alhiane/validatorkit-simplify-ios-data-validation-with-swift-2p7j</link>
      <guid>https://dev.to/alhiane/validatorkit-simplify-ios-data-validation-with-swift-2p7j</guid>
      <description>&lt;h1&gt;
  
  
  ValidatorKit: Simplify iOS Form Validation with Swift
&lt;/h1&gt;

&lt;p&gt;Are you tired of writing repetitive, error-prone form validation code for your iOS apps? Meet ValidatorKit, a lightweight and flexible Swift package designed to streamline form validation in iOS development. Whether you're working with SwiftUI or UIKit, ValidatorKit offers a fluent API that makes defining and applying validation rules a breeze.&lt;/p&gt;

&lt;h2&gt;
  
  
  🚀 Key Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Easy-to-use fluent API&lt;/li&gt;
&lt;li&gt;Support for both SwiftUI and UIKit&lt;/li&gt;
&lt;li&gt;Customizable validation rules&lt;/li&gt;
&lt;li&gt;Lightweight with no external dependencies&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  📦 Installation
&lt;/h2&gt;

&lt;p&gt;Add ValidatorKit to your project using Swift Package Manager:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="nv"&gt;dependencies&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;package&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"https://github.com/Alhiane/ValidatorKit.git"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"1.0.0"&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;
  
  
  🛠️ Usage Examples
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Basic Validation: Single Field, Single Rule
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;ValidatorKit&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;schema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;ValidationSchema&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;field&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="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;required&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ready&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// Always call .ready() to finalize the schema&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;input&lt;/span&gt; &lt;span class="o"&gt;=&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="s"&gt;"user@example.com"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;schema&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&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="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isValid&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="s"&gt;"Email is valid!"&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="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Validation failed: &lt;/span&gt;&lt;span class="se"&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;errors&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="p"&gt;??&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="se"&gt;)&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Multiple Rules for a Single Field
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;schema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;ValidationSchema&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"password"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;required&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"^(?=.*[A-Za-z])(?=.*&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s"&gt;d)[A-Za-z&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s"&gt;d]{8,}$"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ready&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"password"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"pass123"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;schema&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&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;isValid&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="s"&gt;"Password errors: &lt;/span&gt;&lt;span class="se"&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;errors&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&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;span class="se"&gt;)&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Multiple Fields with Multiple Rules
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;schema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;ValidationSchema&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"username"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;required&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;field&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="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;required&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;email&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"age"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;required&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ready&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="s"&gt;"username"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"jo"&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="s"&gt;"not-an-email"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"age"&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="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;schema&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;in&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;errors&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="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\(&lt;/span&gt;&lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="s"&gt; errors: &lt;/span&gt;&lt;span class="se"&gt;\(&lt;/span&gt;&lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="se"&gt;)&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Custom Validation Rules
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;schema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;ValidationSchema&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"password"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;required&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;custom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Password must be at least 8 characters"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;
        &lt;span class="k"&gt;guard&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&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="n"&gt;password&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;8&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;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ready&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"password"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"123abc4567"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;schema&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&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;isValid&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="s"&gt;"Password errors: &lt;/span&gt;&lt;span class="se"&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;errors&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&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;span class="se"&gt;)&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🖼️ SwiftUI Integration
&lt;/h2&gt;

&lt;p&gt;Here's how you can use ValidatorKit in a SwiftUI form:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;SwiftUI&lt;/span&gt;
&lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;ValidatorKit&lt;/span&gt;

&lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;RegistrationForm&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;@State&lt;/span&gt; &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;username&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;
    &lt;span class="kd"&gt;@State&lt;/span&gt; &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;
    &lt;span class="kd"&gt;@State&lt;/span&gt; &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;
    &lt;span class="kd"&gt;@State&lt;/span&gt; &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;validationErrors&lt;/span&gt;&lt;span class="p"&gt;:&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;:&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;]]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[:]&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;schema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;ValidationSchema&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"username"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;required&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;field&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="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;required&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;email&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"password"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;required&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ready&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;Form&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kt"&gt;TextField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Username"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;$username&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="kt"&gt;TextField&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="nv"&gt;text&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="kt"&gt;SecureField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Password"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;text&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="kt"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Register"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;schema&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
                    &lt;span class="s"&gt;"username"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;username&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="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="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="n"&gt;validationErrors&lt;/span&gt; &lt;span class="o"&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;errors&lt;/span&gt;
                &lt;span class="k"&gt;if&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;isValid&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="c1"&gt;// Proceed with registration&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="kt"&gt;ForEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;validationErrors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;keys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sorted&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nv"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;\&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;field&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;errors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;validationErrors&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="kt"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;joined&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;separator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;", "&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
                        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;foregroundColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;red&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;h2&gt;
  
  
  🧪 Testing Your Validation Logic
&lt;/h2&gt;

&lt;p&gt;ValidatorKit makes it easy to test your validation schemas:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;XCTest&lt;/span&gt;
&lt;span class="kd"&gt;@testable&lt;/span&gt; &lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;ValidatorKit&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="kt"&gt;ValidatorKitTests&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;XCTestCase&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;testRegistrationFormValidation&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;schema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;ValidationSchema&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"username"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;required&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;field&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="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;required&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;email&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"password"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;required&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ready&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="c1"&gt;// Test valid input&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;validInput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"username"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"john"&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="s"&gt;"john@example.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"password"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"password123"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;validResult&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;schema&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;validInput&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="kt"&gt;XCTAssertTrue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;validResult&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isValid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;// Test invalid input&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;invalidInput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"username"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"jo"&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="s"&gt;"not-an-email"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"password"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"short"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;invalidResult&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;schema&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;invalidInput&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="kt"&gt;XCTAssertFalse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;invalidResult&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isValid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="kt"&gt;XCTAssertEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;invalidResult&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&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;
  
  
  🎉 Conclusion
&lt;/h2&gt;

&lt;p&gt;ValidatorKit offers a powerful, flexible, and easy-to-use solution for form validation in iOS applications. By providing a fluent API, support for custom rules, and seamless integration with both UIKit and SwiftUI, ValidatorKit simplifies one of the most common and often tedious aspects of iOS development.&lt;/p&gt;

&lt;p&gt;Whether you're building a simple login form or a complex multi-step registration process, ValidatorKit can help you ensure data integrity and improve user experience with minimal effort. Its lightweight design and lack of external dependencies make it an excellent choice for projects of all sizes.&lt;/p&gt;

&lt;h2&gt;
  
  
  📚 Learn More
&lt;/h2&gt;

&lt;p&gt;To dive deeper into ValidatorKit and explore its full potential, check out the &lt;a href="https://github.com/Alhiane/ValidatorKit" rel="noopener noreferrer"&gt;GitHub repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For more iOS development insights and tutorials, visit my personal website at &lt;a href="https://alhiane.com" rel="noopener noreferrer"&gt;https://alhiane.com&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Happy coding! 🚀&lt;/p&gt;

</description>
      <category>ios</category>
      <category>swift</category>
      <category>mobile</category>
      <category>data</category>
    </item>
    <item>
      <title>Tell us how your story began in the world of programming?</title>
      <dc:creator>Alhiane Lahcen</dc:creator>
      <pubDate>Mon, 08 Feb 2021 10:01:52 +0000</pubDate>
      <link>https://dev.to/alhiane/tell-us-how-your-story-began-in-the-world-of-programming-2emj</link>
      <guid>https://dev.to/alhiane/tell-us-how-your-story-began-in-the-world-of-programming-2emj</guid>
      <description>&lt;p&gt;A young Moroccan, I got to know programming at the age of 16, and that was after I met someone and from there the story began &lt;/p&gt;

&lt;p&gt;What about you?&lt;/p&gt;

</description>
      <category>programming</category>
      <category>startup</category>
    </item>
    <item>
      <title>Python makes me a poor programmer !!</title>
      <dc:creator>Alhiane Lahcen</dc:creator>
      <pubDate>Mon, 14 Dec 2020 09:46:02 +0000</pubDate>
      <link>https://dev.to/alhiane/python-makes-me-a-poor-programmer-3cdo</link>
      <guid>https://dev.to/alhiane/python-makes-me-a-poor-programmer-3cdo</guid>
      <description>&lt;p&gt;Python makes me a poor programmer !!&lt;br&gt;
The best of the native programming languages, such as c ++ c and other languages, is that you are familiar with most of the functions scenarios in it and you are forced to demonstrate your strength in creating a logic that is closer to the production of mathematical principles, but # Python dispenses with all these things as it includes a huge library ready, no more efforts&lt;/p&gt;



&lt;blockquote&gt;
&lt;br&gt;
&lt;p&gt;&lt;a href="https://twitter.com/hashtag/Python?src=hash&amp;amp;ref_src=twsrc%5Etfw" rel="noopener noreferrer"&gt;#Python&lt;/a&gt; makes me a poor programmer&lt;br&gt;The best of the native programming languages, is that you are familiar with most of the functions scenarios in it and you are forced to demonstrate your strength in creating a logic that is closer to the production of mathematical principles ,&lt;/p&gt;— Alhiane (@AlhianeLahcen) &lt;a href="https://twitter.com/AlhianeLahcen/status/1338419153301086209?ref_src=twsrc%5Etfw" rel="noopener noreferrer"&gt;December 14, 2020&lt;/a&gt;&lt;br&gt;
&lt;/blockquote&gt; 

</description>
      <category>python</category>
    </item>
    <item>
      <title>Laravel 8</title>
      <dc:creator>Alhiane Lahcen</dc:creator>
      <pubDate>Thu, 10 Sep 2020 09:26:59 +0000</pubDate>
      <link>https://dev.to/alhiane/laravel-8-390e</link>
      <guid>https://dev.to/alhiane/laravel-8-390e</guid>
      <description>&lt;p&gt;تم إصدار Laravel 8 الآن ويتضمن العديد من الميزات الجديدة بما في ذلك Laravel Jetstream , models directory, model factory classes, migration squashing, rate-limiting improvements, time testing helpers, ومكونات الشفرة الديناميكية ، والعديد من الميزات الأخرى.&lt;/p&gt;

&lt;p&gt;قبل الانتقال إلى الميزات الجديدة ، نود الإشارة إلى أنه بدءًا من الإصدار 6 ، يتبع Laravel الآن semver وسيصدر إصدارًا رئيسيًا جديدًا كل ستة أشهر.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://ko5.netlify.app/blog/laravel8/" rel="noopener noreferrer"&gt;Read source article&lt;/a&gt;&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>php</category>
    </item>
    <item>
      <title>لماذا لايهم أي Framework جافاسكريبت تختار ؟</title>
      <dc:creator>Alhiane Lahcen</dc:creator>
      <pubDate>Tue, 04 Aug 2020 12:47:38 +0000</pubDate>
      <link>https://dev.to/alhiane/framework-5795</link>
      <guid>https://dev.to/alhiane/framework-5795</guid>
      <description>&lt;p&gt;خلال مسيرتك البرمجية قد تسأل مرة على الأقل عن لماذا إخترت العمل بإطار معين بدل الآخر كإختيارك مثلا Vue , Angular , React , Svelte .&lt;/p&gt;

&lt;p&gt;وإجابتك غالبا ماتكون أن الإطار سهل في بداية التعلم , أو انه متوافق مع تقنية أستعملها سابقا , وهنا قد يرميك الأخر بالتحيز فقط , أي أنك لم تكن مقتنعا به لولا أنه كان متوافقا مع تلك التقنية السابقة .&lt;/p&gt;

&lt;p&gt;وهذا لايقتصر فقط على إطارات داخل جافاسكريبت بل معمم على جميع بيئات العمل , ولهذا كتبت المقال للحديث أكثر عن موضوع إختيارك لإطار عمل Javascript او للغة أخرى .&lt;/p&gt;

&lt;p&gt;&lt;a href="https://ko5.netlify.app/blog/why-it-doesnt-matter-which-javascript-framework-you-choose/" rel="noopener noreferrer"&gt;تتمة المقالة&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>angular</category>
    </item>
    <item>
      <title>error in winForm c# &amp; sqlite</title>
      <dc:creator>Alhiane Lahcen</dc:creator>
      <pubDate>Fri, 03 Jul 2020 12:14:50 +0000</pubDate>
      <link>https://dev.to/alhiane/error-in-winform-c-sqlite-jj4</link>
      <guid>https://dev.to/alhiane/error-in-winform-c-sqlite-jj4</guid>
      <description>&lt;p&gt;Hi, everyone!&lt;br&gt;
I just finished working on a project using SQLite &amp;amp; c# win Forms.&lt;br&gt;
on mode developer, everything working well.&lt;br&gt;
but when I'm creating setup to my project (using Advanced Installer) and after setup the app on client Machine&lt;br&gt;
I got the error  below&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--e6mJ-dXy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://csharpcorner-mindcrackerinc.netdna-ssl.com/forums/uploadfile/be6744/07022020051351AM/err1.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--e6mJ-dXy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://csharpcorner-mindcrackerinc.netdna-ssl.com/forums/uploadfile/be6744/07022020051351AM/err1.jpg" alt="Alt Text" width="463" height="350"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and there is my code in file app.config and folder structure &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AcFCfPW---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://csharpcorner-mindcrackerinc.netdna-ssl.com/forums/uploadfile/be6744/07022020051351AM/err.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AcFCfPW---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://csharpcorner-mindcrackerinc.netdna-ssl.com/forums/uploadfile/be6744/07022020051351AM/err.jpg" alt="Alt Text" width="800" height="412"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>help</category>
      <category>sqlite</category>
      <category>csharp</category>
    </item>
    <item>
      <title>Promises vs Callbacks in Javascript</title>
      <dc:creator>Alhiane Lahcen</dc:creator>
      <pubDate>Tue, 10 Mar 2020 11:24:41 +0000</pubDate>
      <link>https://dev.to/alhiane/promises-vs-callbacks-in-javascript-k3e</link>
      <guid>https://dev.to/alhiane/promises-vs-callbacks-in-javascript-k3e</guid>
      <description>&lt;p&gt;If you are a professional Javascript programmer, you must have previously worked with the Callbacks function and in some cases, you are forced to use an answer function within an answer function within an answer function and so on (especially when dealing with Asynchronous commands such as AJAX operations and dealing with files and databases, etc. .. .) Until you get a relatively complex and hierarchical code as you will see in the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;isUserTooYoung&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="nf"&gt;openDatabase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
         &lt;span class="nf"&gt;getCollection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;users&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
         &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;col&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
             &lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;col&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; 
             &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                  &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;function &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="p"&gt;{&lt;/span&gt; 
                      &lt;span class="nf"&gt;callback&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="nx"&gt;age&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;18&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;The isUserTooYoung function enables us to confirm that a particular user is an adult (over 18 years old), and for this, the connection is linked to the database, then the user searches to know his age and at last we confirm the age.&lt;/p&gt;

&lt;h1&gt;
  
  
  Use promises
&lt;/h1&gt;




&lt;p&gt;Using promises, we will see that it gives us a clearer, simpler, and more semantic code. Every function that waits for an answer has a function that then picks up the answer from the function before it and passes it to the second function inside. With this concept, we can rewrite the previous code in a more elegant way as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;isUserTooYoung&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&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;openDatabase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getCollection&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;find&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bind&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}))&lt;/span&gt; 
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&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="p"&gt;{&lt;/span&gt; 
            &lt;span class="k"&gt;return&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;age&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;18&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 is code in Node.js, but the idea and process are correct for other JavaScript applications.&lt;/p&gt;

&lt;p&gt;Certainly, now the code has become clearer to you and easier to understand, as we can say that the openDatabase function promised the getCollection function to access certain data Datas after the successful connection to the database, and if we wanted to use the isUserTooYoung function in our program then it would be this way:&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="nf"&gt;isUserTooYoung&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
 &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="c1"&gt;// Here you can deal with the end result&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;



&lt;p&gt;Do not forget that there are other useful functions when using promises in JavaScript, such as the catch function, which is called when an operation or promises is not successful.&lt;/p&gt;

&lt;p&gt;If you want to know more about JAVASCRIPT :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/alhiane/destructuring-functions-in-javascript-es6-3eoh"&gt;Destructuring Functions in javascript Es6
&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="//dev.to/alhiane/object-destructuring-javascript-es6-4g68"&gt;Object Destructuring Javascript ES6
&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/alhiane/array-destructuring-javascript-es6-3e1m"&gt;Array Destructuring Javascript ES6
&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/alhiane/explain-the-steps-of-execution-of-code-in-javascript-591k"&gt;explain the steps of execution of code in JavaScript
&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>productivity</category>
    </item>
    <item>
      <title>What should you do if you find a bug on a platform?</title>
      <dc:creator>Alhiane Lahcen</dc:creator>
      <pubDate>Thu, 20 Feb 2020 20:40:56 +0000</pubDate>
      <link>https://dev.to/alhiane/what-should-you-do-if-you-find-a-bug-on-a-platform-om8</link>
      <guid>https://dev.to/alhiane/what-should-you-do-if-you-find-a-bug-on-a-platform-om8</guid>
      <description>&lt;p&gt;There is no system in this world that is perfect, especially in the field of informatics. Any platform, application, site, program and others may not be that professional that you think. &lt;/p&gt;

&lt;p&gt;You may also find that one day or sometimes you find a loophole or bug in one of the digital platforms that may be your golden opportunity to finally get your spoil, A non knowledge in how to act in this case may be removed Your spoil is about you, and we are here, my friend, to help you as best as possible.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h1&gt;
  
  
  First things first, why would you ever want to report them?
&lt;/h1&gt;


&lt;/blockquote&gt;

&lt;p&gt;I remember a funny conversation that occurred between me and one of the people who may have found a problem in the Facebook platform that enables him to view the messages of other people without having to access their accounts, our friend design this between two options: to report the vulnerability, or to use it to read his girlfriend’s fake messages Doubts wandered around him.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kLH_OIBT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.gridam.com/wp-content/uploads/2019/05/facebook-mobile.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kLH_OIBT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.gridam.com/wp-content/uploads/2019/05/facebook-mobile.jpg" title="facebook bugs" alt="alt text" width="800" height="534"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From a simple point of view, if he would report the vulnerability and then Facebook thanked him for that and closed it is the worst scenario that might happen to him in this case, so he decided to use it to spy on his girlfriend for a period of not less than half a day before Facebook started to close it and suspend the name of one of People who reported it in her celebrity wall, or Hall Of Fame.&lt;/p&gt;

&lt;p&gt;If in the future you encounter the same scenario, do not hesitate to report the vulnerability, why? Because any network, platform or system in this world (especially the famous ones) have what is called an award hunting system or Bounty Program This system allows you to report gaps in sites, applications, programs and platforms, then the vulnerability is evaluated according to its severity (is it A security vulnerability, a vulnerability, just a Bug ...) Then a cash prize is released that matches the rating given.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h1&gt;
  
  
  Platforms that pay you for the vulnerability:
&lt;/h1&gt;


&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jTm8JPPq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://1.bp.blogspot.com/-RcFhaizuZAg/Xkw0nZPqxaI/AAAAAAAAT1w/QbYG057krKsy9QEtha560bC9b3aNQ-zCgCLcBGAsYHQ/s1600/bug.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jTm8JPPq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://1.bp.blogspot.com/-RcFhaizuZAg/Xkw0nZPqxaI/AAAAAAAAT1w/QbYG057krKsy9QEtha560bC9b3aNQ-zCgCLcBGAsYHQ/s1600/bug.jpg" title="report bugs" alt="alt text" width="800" height="230"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In order to help you to know the most prominent platforms and companies that provide Bounty Program services or pay for finding gaps, there is a &lt;a href="https://www.bugcrowd.com/bug-bounty-list/" rel="noopener noreferrer"&gt;bugcrowd&lt;/a&gt; site that provides an alphabetical list of companies that pay you for a system of gaps that do not.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h1&gt;
  
  
  But before reporting your vulnerability make sure:
&lt;/h1&gt;


&lt;/blockquote&gt;

&lt;p&gt;There is no problem, bug, or loophole that you can get a return from, my dear brother. You cannot, for example, sit alone and try to send a message on Facebook and Twitter, and you see an error of a strange type for the first time and you think that it is Bug and accelerate in the Facebook messaging. A few dollars, it doesn’t go like that.&lt;/p&gt;

&lt;p&gt;*First, the vulnerability should be security, meaning that it is a vulnerability in some way that threatens the safety of the user or the safety of the work team, such as the holes that lead to logging into accounts, reading messages, or viewing personal information that another user is not supposed to see.&lt;/p&gt;

&lt;p&gt;*The vulnerability must be tested more than once in more than one way&lt;/p&gt;

&lt;p&gt;*That the defect or the loophole be in the system or the platform itself and not a platform listed in the middle, for example if you use a specific platform and then choose to register via Facebook and then you encounter problems or Bug, this will not be calculated because the problem is only in a third party and not the platform itself.&lt;/p&gt;

&lt;p&gt;*Not to find bugs or bugs in the Alpha or Beta version of a specific platform&lt;/p&gt;

&lt;blockquote&gt;
&lt;h1&gt;
  
  
  How to behave when you find a loophole that fits all of the above?
&lt;/h1&gt;


&lt;/blockquote&gt;

&lt;p&gt;Using the Bugcrowd website and then going directly to the Bug Bounty Program page of the platform in which you discovered a gap, on the page you will find a group of emails and emails or Contact Forms that you can fill out directly in order to establish a connection between you and the site officials. Later, you will receive an answer from the site owners inquiring about some inquiries such as when the vulnerability occurred, how you discovered it, responsible tools and others, and they will ask you if you have a ready solution in advance of the vulnerability, they will accept all your answers and they will correct it or apply instructions that came from you to correct it, they will tell you Also at the price that this platform will pay for such information and a few days after correcting the vulnerability the way you want it will also add your name in the Hall of Fame for people who discovered holes in the platform.&lt;/p&gt;

</description>
      <category>bug</category>
      <category>testing</category>
    </item>
    <item>
      <title>What You Need To Do To Become A Great Developer?</title>
      <dc:creator>Alhiane Lahcen</dc:creator>
      <pubDate>Sun, 16 Feb 2020 20:01:30 +0000</pubDate>
      <link>https://dev.to/alhiane/what-you-need-to-do-to-become-a-great-developer-44b7</link>
      <guid>https://dev.to/alhiane/what-you-need-to-do-to-become-a-great-developer-44b7</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;There are a ton junior developers learning to program for the first time. This is amazing since we always need more programmers, but it means that it is increasingly difficult to standout among the crowd of junior developers. In this video I will be sharing with you the steps that you can take in order to go from a good developer to a great developer and standout from the rest of the crowd. These are the exact steps and processes I took which made me standout far above the competition when applying for my first full time job.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/FNk2NYW-13k"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>python</category>
      <category>devops</category>
      <category>help</category>
    </item>
  </channel>
</rss>
