<?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: ScriptMint</title>
    <description>The latest articles on DEV Community by ScriptMint (@scriptmint).</description>
    <link>https://dev.to/scriptmint</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F787704%2F1d285283-e258-4c6a-8016-9a072eb30a7d.jpg</url>
      <title>DEV Community: ScriptMint</title>
      <link>https://dev.to/scriptmint</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/scriptmint"/>
    <language>en</language>
    <item>
      <title>Integrate Stripe Payment Gateway with Vue 3 and Laravel</title>
      <dc:creator>ScriptMint</dc:creator>
      <pubDate>Sat, 07 Jan 2023 13:17:55 +0000</pubDate>
      <link>https://dev.to/scriptmint/integrate-stripe-payment-gateway-with-vue-3-and-laravel-1gnp</link>
      <guid>https://dev.to/scriptmint/integrate-stripe-payment-gateway-with-vue-3-and-laravel-1gnp</guid>
      <description>&lt;h4&gt;
  
  
  This article is the second part of the payment gateway integration with Vue 3 &amp;amp; Laravel. This time we will discuss integrating Stripe Payment Gateway without using any external package. &lt;a href="https://stripe.com" rel="noopener noreferrer"&gt;Stripe Payment Gateway&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;There are many Vue 3 components available for integrating Stripe Payment Gateway. Though I respect the open-source authors for making such components available for FREE, but I am not a big fan of external packages. I try to keep the number of external packages as low as possible because there are times when package authors don’t update their package (for any reason) or the package has any compatibility issues when you try to update your application.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Simply, if I can create the component myself, I don’t use any external package.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Hi, I am a Full Stack Developer working with Laravel, Vue.js &amp;amp; Tailwind CSS.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Stripe is one of the most popular Payment Gateway which allows you to collect payment worldwide via Credit Card and other payment methods.&lt;/p&gt;

&lt;p&gt;Integrating Stripe Payment Gateway with Vue 3 &amp;amp; Laravel is quite simple.&lt;/p&gt;

&lt;p&gt;To start with the integration, make sure you have an active and verified account with Stripe. Once you signup, you will need to provide some information related to your business. Stripe may take 2–3 working days to activate your account. In my case, I got a verified account in less than 4 hours.&lt;/p&gt;

&lt;p&gt;Once your account is activated, login into the Stripe dashboard. Navigate to Developers -&amp;gt; API Keys and generate key/secret pair for integration.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Before going for any live transactions, you should always test your transactions in test mode. You can generate key/secret pair for the test as well as live mode.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Next, you need to add the Stripe composer package to your Laravel Project which you can do using the below command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer required stripe/stripe-php
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://scriptmint.com/blog/my-macbook-setup-for-development" rel="noopener noreferrer"&gt;How I setup my MacBook setup for Development!&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, We will load the Stripe JS file to process the payment securely and also to ensure that payment details are sent directly to Stripe without hitting other server.&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt; &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://js.stripe.com/v3/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/script&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we will need 3 different APIs to process the payment.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Payment Initiate API&lt;/li&gt;
&lt;li&gt;Payment Success API&lt;/li&gt;
&lt;li&gt;Payment Failure API&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s create these APIs in your route file.&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="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;App\Http\Controller\StripeController&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nc"&gt;Route&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'payment/initiate'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;StripeController&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'initiatePayment'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="nc"&gt;Route&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'payment/complete'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;StripeController&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'completePayment'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="nc"&gt;Route&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'payment/failure'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;StripeController&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'failPayment'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s create StripeController class with initiatePayment method.&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="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Stripe\StripeClient&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;Stripe\PaymentIntent&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\Str&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;Stripe\Stripe&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nc"&gt;StripeGateway&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;initiatePayment&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="nc"&gt;StripeGateway&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;setApiKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'STRIPE_SECRET_KEY'&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="nv"&gt;$paymentIntent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;PaymentIntent&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
            &lt;span class="s1"&gt;'amount'&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;amount&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Multiply as &amp;amp; when required&lt;/span&gt;
            &lt;span class="s1"&gt;'currency'&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;currency&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'automatic_payment_methods'&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;'enabled'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&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="p"&gt;]);&lt;/span&gt;

        &lt;span class="c1"&gt;// Save the $paymentIntent-&amp;gt;id to identify this payment later&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="nc"&gt;Exception&lt;/span&gt; &lt;span class="nv"&gt;$e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// throw 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;[&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="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="nc"&gt;Str&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="s1"&gt;'client_secret'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$paymentIntent&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;client_secret&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;Stripe processes the amount in cents for maximum currency i.e. you need to multiply the amount by 100. There are some zero decimal currencies like JPY which don’t need any multiplication.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To initiate a payment, we first need to create a Payment Intent with Stripe Payment Gateway. We will pass the amount and the currency of the payment and save this Payment Intent for future use.&lt;/p&gt;

&lt;p&gt;This Payment Intent also generates a Client Secret which we will pass as a response.&lt;/p&gt;

&lt;p&gt;Now, we will create a Payment.vue component 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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;form&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;payment-form&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;payment-element&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="c"&gt;&amp;lt;!--&lt;/span&gt; &lt;span class="nx"&gt;Stripe&lt;/span&gt; &lt;span class="nx"&gt;will&lt;/span&gt; &lt;span class="nx"&gt;create&lt;/span&gt; &lt;span class="nx"&gt;form&lt;/span&gt; &lt;span class="nx"&gt;elements&lt;/span&gt; &lt;span class="nx"&gt;here&lt;/span&gt; &lt;span class="o"&gt;--&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;submit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;click&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;handleSubmit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Pay&lt;/span&gt; &lt;span class="nx"&gt;via&lt;/span&gt; &lt;span class="nx"&gt;Stripe&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/form&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/template&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt; &lt;span class="nx"&gt;setup&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;onMounted&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;vue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ref&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;stripe&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ref&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;elements&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ref&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;onMounted&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="nx"&gt;axios&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;INITIATE_PAYMENT_API&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="na"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;150&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;currency&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;USD&lt;/span&gt;&lt;span class="dl"&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;response&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&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;token&lt;/span&gt; &lt;span class="c1"&gt;// Use to identify the payment&lt;/span&gt;
        &lt;span class="nx"&gt;stripe&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Stripe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;STRIPE_PUBLISHABLE_KEY&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;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;clientSecret&lt;/span&gt;&lt;span class="p"&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;clientSecret&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="nx"&gt;elements&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;stripe&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;elements&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;options&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;paymentElement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;elements&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;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;payment&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;paymentElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#payment-element&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;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// throw error&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;handleSubmit&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="nx"&gt;e&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="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;preventDefault&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="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;stripe&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;confirmPayment&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;elements&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;elements&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="na"&gt;redirect&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;if_required&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="nx"&gt;error&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;axios&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;PAYMENT_SUCCESS_API&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="na"&gt;token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;token&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="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="nx"&gt;axios&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;PAYMENT_FAILURE_API&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="na"&gt;token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;token&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="na"&gt;code&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;code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;description&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;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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/script&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are basically creating an empty form without any input. The reason for creating an empty form is that Stripe Payment Gateway dynamically creates form input and Credit Card details are sent securely to the Stripe server only.&lt;/p&gt;

&lt;p&gt;The mounted method of the component generates the form dynamically by using the publishable key &amp;amp; client secret sent by the payment initiates API.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsck6xut3dwdhqvc0r8is.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsck6xut3dwdhqvc0r8is.png" alt="Stripe Payment Gateway" width="800" height="508"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you click on the “Pay via Stripe” button, the handleFunction confirms the payment with the Stripe server.&lt;/p&gt;

&lt;p&gt;If the payment is successful i.e. there is no error with the payment, you can call the Payment Success API with the token you received during Payment Initiate API.&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="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Stripe\StripeClient&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="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;completePayment&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;$stripe&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;StripeClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'STRIPE_SECRET_KEY'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Use the payment intent ID stored when initiating payment&lt;/span&gt;
    &lt;span class="nv"&gt;$paymentDetail&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$stripe&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;paymentIntents&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;retrieve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'PAYMENT_INTENT_ID'&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;$paymentDetail&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s1"&gt;'succeeded'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// throw error&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Complete the payment&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In case of any error, you can call Payment Failure API with the error details.&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="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="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;failPayment&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="c1"&gt;// Log the failed payment if you wish&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Creating your own component to do the job always feels good. You are basically no longer dependent on any other external package.&lt;/p&gt;

&lt;p&gt;If you face any issues or have any query, you can write me at &lt;a href="mailto:hello@scriptmint.com"&gt;hello@scriptmint.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://scriptmint.com/blog/integrate-razorpay-payment-gateway-with-vue3-laravel" rel="noopener noreferrer"&gt;Integrate Razorpay Payment Gateway with Vue 3 &amp;amp; Laravel&lt;/a&gt;&lt;/p&gt;

</description>
      <category>gratitude</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Integrate Razorpay Payment Gateway with Vue 3 and Laravel</title>
      <dc:creator>ScriptMint</dc:creator>
      <pubDate>Sun, 11 Dec 2022 03:36:19 +0000</pubDate>
      <link>https://dev.to/scriptmint/integrate-razorpay-payment-gateway-with-vue-3-and-laravel-328p</link>
      <guid>https://dev.to/scriptmint/integrate-razorpay-payment-gateway-with-vue-3-and-laravel-328p</guid>
      <description>&lt;h4&gt;
  
  
  I am starting a blog series for payment gateway integration with Vue 3 &amp;amp; Laravel. Let's start with &lt;a href="https://razorpay.com"&gt;Razorpay Payment Gateway&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;Hi, I am a Full Stack Developer working with Laravel, Vue.js &amp;amp; Tailwind CSS.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Razorpay is one of the most popular Payment Gateways in India which offers you to collect payment via Credit/Debit Card, Net Banking, UPI, Wallet etc.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Integrating Razorpay Payment Gateway with Vue 3 &amp;amp; Laravel is quite simple.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you are familiar with Stripe Integration, then you will find Razorpay Integration almost similar.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To start with the integration, make sure you have an active and verified account with Razorpay. Once you signup, you will need to upload KYC documents. Razorpay takes 2-3 working days to activate your account.&lt;/p&gt;

&lt;p&gt;Once your account is activated, login into Razorpay dashboard. Navigate to Setting -&amp;gt; API Keys and generate key/secret pair for integration.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Before going for any live transactions, you should always test your transactions in the test mode. You can generate key/secret pair for test as well as live mode.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Next, you need to add Razorpay composer package to your Laravel Project which you can do using below command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;composer required razorpay/razorpay
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, We will use Razorpay Checkout.js file to invoke Payment Modal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;script src="https://checkout.razorpay.com/v1/checkout.js"&amp;gt;&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the script is loaded, you can initialize the Razorpay function with options in the onMounted method.&lt;/p&gt;

&lt;p&gt;Let's create a Payment.vue component as following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;template&amp;gt;
    &amp;lt;button @click="pay"&amp;gt;Pay via Razorpay&amp;lt;/button&amp;gt;
&amp;lt;/template&amp;gt;

&amp;lt;script setup&amp;gt;
import { onMounted } from "vue"

const pay = () =&amp;gt; {
    rzp.open();
}

onMounted(() =&amp;gt; {
    var options = {
        "key": "YOUR_KEY_ID", // Enter the Key ID generated from the Razorpay Setting -&amp;gt; API Keys
        "amount": "50000", // Amount is in currency. Default currency is INR. Hence, 50000 refers to 50000 paise
        "currency": "INR",
        "name": "ScriptMint",
        "description": "Test Transaction",
        "image": "https://example.com/your_logo",
        "handler": function (response){
            axios.post("PAYMENT_SUCCESS_API", {
                payment_id: response.razorpay_payment_id,
                order_id: response.razorpay_order_id,
            })
            .then(function (response) {
                // Show success message
            })
            .catch(function (error) {
                // Show failed message
            });
        },
        "prefill": {
            "name": "Customer Name",
            "email": "customer.email@example.com",
            "contact": "9999999999"
        },
        "notes": {
            "address": "Customer Address"
        },
        "theme": {
            "color": "#3399cc"
        }
    };
    var rzp = new Razorpay(options);

    rzp.on('payment.failed', function (response){
        axios.post("PAYMENT_FAILURE_API", {
            payment_id: response.razorpay_payment_id,
            order_id: response.razorpay_order_id,
            code: response.error.code,
            description: response.error.description,
        })
        .then(function (response) {
            // Show failed message
        })
        .catch(function (error) {
            // Show error message
        });
    });
})
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Installing Xdebug on Macos with VS Code! &lt;a href="https://scriptmint.com/blog/installing-xdebug3-macos-debug-vscode"&gt;Read this article here&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The options contain your Razorpay Key ID, amount you would like to pay, currency and other keys which are self-explanatory etc.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Please note that we are not passing any order_id key in this options object. If you would like to create an order, then you can include it in the object.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The component also contains a button to make the payment. Once the user clicks on the pay button, it opens a modal window with prefilled name, email &amp;amp; contact number.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AeHJF1uw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q4pny8mt8rmss4mguriv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AeHJF1uw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q4pny8mt8rmss4mguriv.png" alt="Image description" width="880" height="733"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can click on the proceed button and choose the payment method.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mFrJKVji--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/le3nt8737h1s0d3zrmjv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mFrJKVji--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/le3nt8737h1s0d3zrmjv.png" alt="Image description" width="880" height="737"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then handler function is called on successful payment. You can send the payment information like payment_id, order_id or signature to Laravel API to verify the payment.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3mAXpYBb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fong5i8ax31n5g5h095u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3mAXpYBb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fong5i8ax31n5g5h095u.png" alt="Image description" width="880" height="727"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, you need to verify the payment which you can do via Laravel API as below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use Razorpay\Api\Api;
use Illuminate\Http\Request;

public function validatePayment(Request $request)
{
    $api = new Api('RAZORPAY_KEY_ID', 'RAZORPAY_KEY_SECRET');

    $paymentDetail = $api-&amp;gt;payment-&amp;gt;fetch($request-&amp;gt;payment_id)-&amp;gt;toArray();

    $status = Arr::get($paymentDetail, 'status');

    if ($status != 'authorized') {
        // Throw error
    }

    // Complete the payment
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Similarly, on payment failure, you can call the failed callback function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use Illuminate\Http\Request;

public function logFailedPayment(Request $request)
{
    // Log the failed payment if you wish
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, you need to pass the Razorpay Key ID &amp;amp; Secret to create API object which is used to fetch the detail of the payment ID. You can check the status which when authorized can be used to make the payment as paid.&lt;/p&gt;

&lt;p&gt;If you are not a technical person then also you can accept payment via Razorpay. It offers multiple ways to collect payments like Payment Links, Payment Pages, Invoicing, Subscription etc.&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>vue</category>
      <category>razorpay</category>
      <category>payment</category>
    </item>
    <item>
      <title>Installing Xdebug 3 on MacOS and Debug in VS Code</title>
      <dc:creator>ScriptMint</dc:creator>
      <pubDate>Mon, 28 Nov 2022 10:58:59 +0000</pubDate>
      <link>https://dev.to/scriptmint/installing-xdebug-3-on-macos-and-debug-in-vs-code-3l5h</link>
      <guid>https://dev.to/scriptmint/installing-xdebug-3-on-macos-and-debug-in-vs-code-3l5h</guid>
      <description>&lt;h4&gt;
  
  
  I always found setting up Xdebug as one of the most difficult job. But today, I did it under 5 minutes.
&lt;/h4&gt;

&lt;p&gt;Hi, I am a Full Stack Developer working with Laravel, Vue.js &amp;amp; Tailwind CSS.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you don't use right tool for debugging, you may end up spending your whole day by doing nothing.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;How do you debug your code in PHP? Do you use var_dump or dd in Laravel? Many of us also use logger to log output &amp;amp; figure out the problem in multiple steps. &lt;a href="https://spatie.be" rel="noopener noreferrer"&gt;Spatie&lt;/a&gt; built a debugging tool called &lt;a href="https://spatie.be/products/ray" rel="noopener noreferrer"&gt;Ray&lt;/a&gt; that one can use to simplify the operation over dd or logger.&lt;/p&gt;

&lt;p&gt;I like to debug Laravel application with Xdebug. Xdebug is an extension for PHP, and provides a range of features to improve the PHP development experience.&lt;/p&gt;

&lt;p&gt;Today after I reset my MacBook, I had to setup Xdebug and I did the installation under 5 minutes. So I thought to write a blog explaining how easy it is to setup Xdebug.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Earlier, whenever I used to install Xdebug, I had to look for multiple articles to make it work. Let me clarify, you don't need any Chrome Extension and also you don't need too much configurations. Its super simple.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I use &lt;a href="https://brew.sh" rel="noopener noreferrer"&gt;Homebrew&lt;/a&gt; to install various packages on my MacBook. I have already installed PHP 8.1 using homebrew by running below command:&lt;/p&gt;

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

brew install php@8.1


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

&lt;/div&gt;

&lt;p&gt;Next, you need to install Xdebug PHP Extension which you can install using below command.&lt;/p&gt;

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

pecl install xdebug


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

&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;My MacBook Setup for Development! &lt;a href="https://scriptmint.com/blog/my-macbook-setup-for-development" rel="noopener noreferrer"&gt;Read this article here&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Next, you must enable this extension in your php.ini file. To enable it, locate the php.ini file location. In my case it is located under /usr/local/etc/php directory.&lt;/p&gt;

&lt;p&gt;You can either edit your php.ini file and add some config option for Xdebug or create a separate config file for this extension. I choose to go with second option and created a file called ext-xdebug.ini under /usr/local/etc/php/conf.d directory. You just need to put below config in this ext-xdebug.ini file.&lt;/p&gt;

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

zend_extension="xdebug.so"
xdebug.mode=debug
xdebug.start_with_request=yes


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

&lt;/div&gt;

&lt;p&gt;If you wish edit your php.ini file, you can put these lines at the bottom.&lt;/p&gt;

&lt;p&gt;Restart the PHP service using brew command:&lt;/p&gt;

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

brew servcies restart php


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

&lt;/div&gt;

&lt;p&gt;Next, you can run php --version command to check if shows Xdebug extension.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1400%2F1%2A0NDhP-_V-KLZ8rh_V00WvQ.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1400%2F1%2A0NDhP-_V-KLZ8rh_V00WvQ.webp" alt="PHP with Xdebug"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Alternatively, You can call phpinfo function in any PHP file and it should show Xdebug related information.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1400%2F1%2Aubg-49j8EUZtwS8vUvMSyQ.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1400%2F1%2Aubg-49j8EUZtwS8vUvMSyQ.webp" alt="PHPInfo with Xdebug"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, Open VS Code &amp;amp; Install PHP Debug Extension.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1400%2F1%2AWuoRAsC2m3-Opqan9HIFyA.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1400%2F1%2AWuoRAsC2m3-Opqan9HIFyA.webp" alt="PHP Debug"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, open your project in VS Code, create launch.json config file under .vscode directory with following content:&lt;/p&gt;

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

{
    "configurations": [
        {
            "name": "Listen for Xdebug",
            "type": "php",
            "request": "launch",
            "port": 9003,
        }
    ]
}


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

&lt;/div&gt;

&lt;p&gt;This is project specific setting which you need to do in every project wherever you wish to debug your application using Xdebug.&lt;/p&gt;

&lt;p&gt;By default Xdebug is listening to port 9003 as you can see in the VS Code PHP Debug extension.&lt;/p&gt;

&lt;p&gt;That's all you need to do. Its super simple.&lt;/p&gt;

&lt;p&gt;Now its time to debug your application. Open any PHP file, put a breakpoint, press F5 to start debugging and navigate to your browser. You will be redirected back to the VS Code at the same line where you put a breakpoint.&lt;/p&gt;

&lt;p&gt;Here, I opened Laravel's web.php file and put a breakpoint. Here is the screenshot of debugging:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1400%2F1%2A8RpFE4-cmBH2NLRfU4u2QA.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1400%2F1%2A8RpFE4-cmBH2NLRfU4u2QA.webp" alt="Live Debugging"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can use the control buttons to perform various moves.&lt;/p&gt;

&lt;p&gt;I love code debugging using Xdebug. It can save your precious time &amp;amp; also improves the productivity.&lt;/p&gt;

</description>
      <category>xdebug</category>
      <category>vscode</category>
      <category>php</category>
      <category>laravel</category>
    </item>
    <item>
      <title>I am in love with my VS Code Setup!</title>
      <dc:creator>ScriptMint</dc:creator>
      <pubDate>Fri, 11 Feb 2022 17:03:40 +0000</pubDate>
      <link>https://dev.to/scriptmint/i-am-in-love-with-my-vs-code-setup-5h79</link>
      <guid>https://dev.to/scriptmint/i-am-in-love-with-my-vs-code-setup-5h79</guid>
      <description>&lt;p&gt;If you are a developer and don't fall in love with your dev environment, then most probably you are missing something &amp;amp; you will not be as productive as you can.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Attention: I am a Full Stack Developer mostly working with Laravel, Vue.js &amp;amp; Tailwind CSS. I have setup VS Code as per my requirement.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I remember, In mid 2008 during college days, I used to write codes in Notepad. It was hard to write code without any suggestions and formatting any piece of code was not an easy job (Most of my time was spent on matching bracket pairs). At that time I thought, Notepad is the best editor to do this job.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VUtb1trg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1644598061502/8YYNFEqke.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VUtb1trg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1644598061502/8YYNFEqke.png" alt="image.png" width="400" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then I found Notepad++ with Multi Tab support and Bracket Pair identifier.&lt;/p&gt;

&lt;p&gt;One day my friend told me about Sublime Text Editor and then I realised what the **** I was doing till date. The most favourite part of Sublime Editor was Multi Cursor support and its theme. First time I saw the Dark Theme and then never get back to the told Light Theme in my career. I also learn about quickly searching files, extensions and key bindings. Everything is awesome! (I still use to work with Sublime Text Editor whenever I need two separate editors)&lt;/p&gt;

&lt;p&gt;I was quite happy with Sublime and it was really helping me to do my job quickly and then one day (Early 2018) I checked &lt;a href="https://twitter.com/jeffrey_way"&gt;Jeffrey Way&lt;/a&gt; explaining a course "&lt;a href="https://laracasts.com/series/visual-studio-code-for-php-developers"&gt;Visual Studio Code for PHP Developers&lt;/a&gt;" on Laracasts. Do subscribe if you haven't!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HpuX-mPB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1644598072788/CmcKc1VhR.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HpuX-mPB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1644598072788/CmcKc1VhR.png" alt="image.png" width="880" height="366"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;VS Code for PHP Developers on LaracastsI checked the whole series that night and then moved to VS Code immediately (like always I did). Today I feel that VS Code has completed my dev environment and I can do my job quickly &amp;amp; efficiently. In other words, my productivity has increased multi-fold.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This time I convinced my friend to use VS Code who suggested me to use Sublime and Today, we both are using VS Code with almost similar setting.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;VS Code has almost everything in it a developer may need. With the integration of Terminal &amp;amp; Git, it usually completes the developer requirement.&lt;/p&gt;

&lt;p&gt;In May 2020, I found a guy on Twitter talking about his VS Code setup and I quickly subscribed to his email. He sent 7 newsletter and it blown up my mind. He is none other than &lt;a href="https://twitter.com/calebporzio"&gt;Caleb Porzio&lt;/a&gt;. Caleb has written a complete course with book, videos to make your VS Code experience awesome.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yRk3gRYb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1644598081825/VY_Dg1R-I.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yRk3gRYb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1644598081825/VY_Dg1R-I.png" alt="image.png" width="880" height="504"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All the credits for my VS Code setup goes to either &lt;a href="https://twitter.com/jeffrey_way"&gt;Jeffrey Way&lt;/a&gt; or &lt;a href="https://twitter.com/calebporzio"&gt;Caleb Porzio&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The first thing Caleb said in his newsletter was "Less is more". I understand it as:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Remove everything that can distract your mind.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And I did the same. Believe me, it is one of the thing you will do to setup your Code Editor. Here is the preview of VS Code setup!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kvY_vK4E--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1644598386805/q66nn1wGP.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kvY_vK4E--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1644598386805/q66nn1wGP.png" alt="image.png" width="880" height="622"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I am serious and not joking! I have removed everything that can distract my mind. And now I have much bigger space to write code.&lt;/p&gt;

&lt;p&gt;The second best thing I did is placed the sidebar to the right side (In case I need it). You usually write from left to right, so it feels like typical notebook writing where you don't have any margin or space in the left.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YogUU-sv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1644598195316/eHjcvCkZn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YogUU-sv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1644598195316/eHjcvCkZn.png" alt="image.png" width="880" height="623"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here are details of my VS Code setup:&lt;/p&gt;

&lt;h3&gt;
  
  
  Theme:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=smlombardi.slime"&gt;Slime Theme&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.typography.com/fonts/operator/styles/operatormono"&gt;Operator Mono&lt;/a&gt; Font Size 20&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Key Bindings:
&lt;/h3&gt;

&lt;p&gt;I was much used to Sublime Text key binding, so many of key bindings are imported from Sublime. Here are my top 10 Key Bindings that I use daily countless time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cmd + K, Cmd + B: Toggle Sidebar Visibility&lt;/li&gt;
&lt;li&gt;Cmd + Shift + A: Align Code&lt;/li&gt;
&lt;li&gt;Ctrl + Shift+ Space: Collapse Explored Folder&lt;/li&gt;
&lt;li&gt;Cmd + Alt + P: Open Project Manager&lt;/li&gt;
&lt;li&gt;Cmd + Shift + D: Duplicate line&lt;/li&gt;
&lt;li&gt;Cmd + J: Toggle Terminal&lt;/li&gt;
&lt;li&gt;Ctrl + Shift + E: Open File Explorer&lt;/li&gt;
&lt;li&gt;Shift + ` : Show Setting (Preferences)&lt;/li&gt;
&lt;li&gt;Cmd + C, Cmd + S: Codespace&lt;/li&gt;
&lt;li&gt;Cmd + 2: Split Editor&lt;/li&gt;
&lt;li&gt;Ctrl + Space: Show Suggestions (Bonus)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are many others key bindings which I use regularly. What I have experienced is that you don't need to remember these key bindings. The more you work with your Dev Environment, more quickly it becomes your habit and suddenly you will notice that your fingers will do the job automatically while you do not care about it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Extensions:
&lt;/h3&gt;

&lt;p&gt;Here are my top 10 extensions that I found most useful.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=alefragnani.project-manager"&gt;Project Manager&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=calebporzio.better-phpunit"&gt;Better PHPUnit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=adpyke.codesnap"&gt;CodeSnap&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=wmaurer.change-case"&gt;Change Case&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=formulahendry.auto-rename-tag"&gt;Auto Rename Tag&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=ryannaddy.laravel-artisan"&gt;Laravel Artisan&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode"&gt;Prettier&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=octref.vetur"&gt;Vetur&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=bmewburn.vscode-intelephense-client"&gt;PHP Intelephense&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss"&gt;Tailwind CSS IntelliSense&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Snippets:
&lt;/h3&gt;

&lt;p&gt;Snippets are another great feature of VS Code. Snippets are piece of code you use frequently that you can write or generate using shortcuts. You can generate snippet for any programming language you are working with. VS Code saves these snippets in particular language json file which you can directly edit. You can also create global snippet file that can be used in any language.&lt;/p&gt;

&lt;p&gt;Here is an example of Vue Snippet. When I use to type "vuecomp", it suggest to use this snippet and immediately import following code for me:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rPg55L9H--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7tk08zkfrfj9tmqeroax.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rPg55L9H--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7tk08zkfrfj9tmqeroax.png" alt="Image description" width="880" height="616"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;h3&gt;
  
  
  Git:
&lt;/h3&gt;

&lt;p&gt;The shortcut key to get Git Panel in my VS Code is Cmd + Shift+ G. VS Code Git integration offers variety of operations which you usually do with Terminal. You can add file, commit with message, push easily with this panel. You don't need to leave your VS Code for such actions.&lt;/p&gt;

&lt;p&gt;Moreover, you can see all available branches, switch to any branch and also view stash from your VS Code.&lt;/p&gt;

&lt;p&gt;One of my favourite Git Action is Undo Commit. If you have committed anything by mistake, you can easily undo it with single click.&lt;/p&gt;

&lt;h3&gt;
  
  
  Terminal:
&lt;/h3&gt;

&lt;p&gt;VS Code offers inbuilt Terminal. In my setup, I can type Cmd + J and toggle its visibility. It also supports multiple tabs and can perform all the actions which you usually perform in your terminal.&lt;/p&gt;

&lt;h3&gt;
  
  
  Debugging:
&lt;/h3&gt;

&lt;p&gt;I am not regular user of PHP Xdebug but tried it with VS Code and it works well with it. Setting up PHP Xdebug can be a separate article, I will definitely plan it in future.&lt;/p&gt;

&lt;p&gt;With these setup, whenever I open my VS Code, I immediately fall in love with it. I keep improving my VS Code working experience by searching for new features, extensions.&lt;/p&gt;

&lt;p&gt;I hope you like this VS Code setup. Do share yours, let's learn by sharing!&lt;/p&gt;

</description>
      <category>vscode</category>
      <category>productivity</category>
      <category>microsoft</category>
      <category>development</category>
    </item>
    <item>
      <title>Vue3 Tailwind Form Components Part IV - Reusable BaseRadio Component</title>
      <dc:creator>ScriptMint</dc:creator>
      <pubDate>Thu, 10 Feb 2022 03:20:45 +0000</pubDate>
      <link>https://dev.to/scriptmint/vue3-tailwind-form-components-part-iv-reusable-baseradio-component-1610</link>
      <guid>https://dev.to/scriptmint/vue3-tailwind-form-components-part-iv-reusable-baseradio-component-1610</guid>
      <description>&lt;p&gt;This is fourth article of &lt;a href="https://dev.to/scriptmint/series/16710"&gt;Vue3 Tailwind Form Components Series&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Form Components are very important for any Web Application. Think about a project without proper Form Components with multiple forms in it. What if you need to change design of your radio input or you wish to add extra functionality into radio input? I did the same mistake in 2018 when using Vue2 and still my project is not easy to maintain.&lt;/p&gt;

&lt;p&gt;Live Demo: &lt;a href="https://scriptmint-solution.github.io/vue3-tailwind-form-components/"&gt;https://scriptmint-solution.github.io/vue3-tailwind-form-components/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;GitHub Repository: &lt;a href="https://github.com/scriptmint-solution/vue3-tailwind-form-components"&gt;https://github.com/scriptmint-solution/vue3-tailwind-form-components&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Do check our Advanced Featured Admin Panel at &lt;a href="https://scriptmint.com/vana-admin"&gt;Vana Admin&lt;/a&gt; built with Laravel, Vue.js 3 &amp;amp; Tailwind CSS 3 with tons of inbuilt features to quickly build your next project.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  BaseRadio
&lt;/h3&gt;

&lt;p&gt;Building BaseRadio component is little complex. Let's build together.&lt;/p&gt;

&lt;p&gt;We will start with a basic radio input.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;template&amp;gt;
    &amp;lt;div class="flex items-center"&amp;gt;
        &amp;lt;input
            type="radio"
            class="focus:ring-0 h-4 w-4"
        /&amp;gt;
        &amp;lt;label class="ml-2 block text-sm text-gray-900"&amp;gt;
            label goes here!
        &amp;lt;/label&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/template&amp;gt;

&amp;lt;script&amp;gt;
export default {
    name: 'BaseRadio',
    inheritAttrs: false
}
&amp;lt;/script&amp;gt;

&amp;lt;script setup&amp;gt;
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I hope you understand the meaning of inheritAttrs by now. If not, please refer to our previous articles of this series.&lt;/p&gt;

&lt;p&gt;Above we created a simple radio button and a label for its description. Each radio button should have an option and similar to checkbox input, it can be checked. So let's modify this component to accept value and add change event on it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;input
    v-bind="$attrs"
    :checked="modelValue === value"
    @change="updateInput"
    :value="value"
    type="radio"
    class="focus:ring-0 h-4 w-4"
/&amp;gt;
&amp;lt;label class="ml-2 block text-sm text-gray-900"&amp;gt;
    {{label}}
&amp;lt;/label&amp;gt;

...
...

&amp;lt;script setup&amp;gt;
const emit = defineEmits(['update:modelValue'])

const props = defineProps({
    label: {
        type: String,
        default: ''
    },
    modelValue: {
        type: [String, Number],
        default: ''
    },
    value: {
        type: [String, Number],
        required: true,
    }
})

const updateInput = ($event) =&amp;gt; {
    emit('update:modelValue', $event.target.value)
}
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we are passing three props to the component. We also bind the value of the radio input to the value property. To check whether the radio input will be selected or not, we have compared the modelValue with the given value.&lt;/p&gt;

&lt;p&gt;At the change event of radio input, we will emit an event to the component with the value.&lt;/p&gt;

&lt;p&gt;So, we have done with the BaseRadio component. What next?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Radio Inputs are always used for multiple options. You never use it for single option (Checkbox is available for this purpose)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So how can we generate BaseRadio component for multiple options? We will create another component BaseRadioGroup. Let's see how!&lt;/p&gt;

&lt;p&gt;Create BaseRadioGroup.vue file in the components folder.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;template&amp;gt;
    &amp;lt;div class="flex space-x-4"&amp;gt;
        &amp;lt;BaseRadio
            v-for="option in options"
            :label="option.label"
            :value="option.value"
            :name="name"
            v-model="modelValue"
            @update:modelValue="updateInput"
        /&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/template&amp;gt;

&amp;lt;script&amp;gt;
export default {
    name: 'BaseRadioGroup',
    inheritAttrs: false
}
&amp;lt;/script&amp;gt;

&amp;lt;script setup&amp;gt;
import BaseRadio from './BaseRadio.vue'
const emit = defineEmits(['update:modelValue'])

const props = defineProps({
    options: {
        type: Array,
        required: true
    },
    name: {
        type: String,
        required: true
    },
    modelValue: {
        type: [String, Number],
        required: true
    }
})

const updateInput = ($event) =&amp;gt; {
    emit('update:modelValue', $event)
}
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this component, we are passing three properties: An array of options, name for the radio input &amp;amp; model value (i.e. v-model)&lt;/p&gt;

&lt;p&gt;We are looping through the options and generating BaseRadio component for each option by passing label &amp;amp; value attribute. Also we are binding v-model to the given  modelValue (Used to pre-select option).&lt;/p&gt;

&lt;p&gt;We are also listening to update:modelValue event and emiting event to its parent component.&lt;/p&gt;

&lt;p&gt;So we have completed our BaseRadio &amp;amp; BaseRadioGroup component. Let's see how can we use it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;BaseRadioGroup
    :options="[
        {label: 'Option 1', value: 'option1'},
        {label: 'Option 2', value: 'option2'},
    ]"
    name="option"
    v-model="sampleRadio"
/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hope you get the idea behind this component. Checkout the full source code in the GitHub repository at &lt;a href="https://github.com/scriptmint-solution/vue3-tailwind-form-components"&gt;https://github.com/scriptmint-solution/vue3-tailwind-form-components&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Do let your feedback or suggestion to improve this component.&lt;/p&gt;

</description>
      <category>vue</category>
      <category>tailwindcss</category>
      <category>forms</category>
      <category>components</category>
    </item>
    <item>
      <title>Vue3 Tailwind CSS Form Components Part III - Reusable BaseCheckbox Component</title>
      <dc:creator>ScriptMint</dc:creator>
      <pubDate>Wed, 09 Feb 2022 03:33:54 +0000</pubDate>
      <link>https://dev.to/scriptmint/vue3-tailwind-css-form-components-part-iii-reusable-basecheckbox-component-14l5</link>
      <guid>https://dev.to/scriptmint/vue3-tailwind-css-form-components-part-iii-reusable-basecheckbox-component-14l5</guid>
      <description>&lt;p&gt;This is third part of &lt;a href="https://dev.to/scriptmint/series/16710"&gt;Vue3 Tailwind Form Components Series&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Form Components are very important for any Web Application. Think about a project without proper Form Components with multiple forms in it. What if you need to change design of your checkbox input or you wish to add extra functionality into checkbox input? I did the same mistake in 2018 when using Vue2 and still my project is not easy to maintain.&lt;/p&gt;

&lt;p&gt;Live Demo: &lt;a href="https://scriptmint-solution.github.io/vue3-tailwind-form-components/"&gt;https://scriptmint-solution.github.io/vue3-tailwind-form-components/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;GitHub Repository: &lt;a href="https://github.com/scriptmint-solution/vue3-tailwind-form-components"&gt;https://github.com/scriptmint-solution/vue3-tailwind-form-components&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Do check our Advanced Featured Admin Panel at &lt;a href="https://scriptmint.com/vana-admin"&gt;Vana Admin&lt;/a&gt; built with Laravel, Vue.js 3 &amp;amp; Tailwind CSS 3 with tons of inbuilt features to quickly build your next project.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  BaseCheckbox
&lt;/h3&gt;

&lt;p&gt;Lets start with this Component:&lt;/p&gt;

&lt;p&gt;Here is the Code, we would like to get a Custom Checkbox Component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;BaseCheckbox id="name" name="name" label="Sample Checkbox" /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will start with a very basic checkbox component. Create a BaseCheckbox.vue file inside your components directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;template&amp;gt;
    &amp;lt;div&amp;gt;
        &amp;lt;input
              type="checkbox"
              class="h-4 w-4 focus:ring-0 cursor-pointer rounded"
        /&amp;gt;
        &amp;lt;label class="ml-2 block text-sm text-gray-900 cursor-pointer"&amp;gt;
              label goes here!
        &amp;lt;/label&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/template&amp;gt;

&amp;lt;script&amp;gt;
export default {
    name: 'BaseCheckbox',
    inheritAttrs: false
}
&amp;lt;/script&amp;gt;

&amp;lt;script setup&amp;gt;
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have only applied some css classes to make it look better. Lets add some props now. Also note that we have set inheriAttrs property to false, as we wish to bind the attributes of BaseCheckbox to the input field (Not with the root element).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;script setup&amp;gt;
const props = defineProps({
    label: {
        type: String,
        default: ''
    },
    modelValue: {
        type: [String, Number],
        default: ''
    }
})
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In Vue3, you can pass v-model attribute in your component and it will be available as modelValue inside your component. Also, we need to bind this modelValue to the value attribute of the input field. &lt;/p&gt;

&lt;p&gt;Next, we need to emit the value everytime whenever user check or uncheck it. To do so, we will make:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;input 
    v-bind="$attrs"
    :checked="modelValue"
    @change="updateInput"
    type="checkbox"
    rows="3" class="w-full shadow appearance-none border rounded py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
/&amp;gt;
...
...

const emit = defineEmits(['update:modelValue'])

const updateInput = ($event) =&amp;gt; {
    emit('update:modelValue', $event.target.checked)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we bind the attributes to the the field which emits the value of the checkbox field and make it available to the BaseCheckbox component v-model attribute via two way binding.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Unlike BaseInput or BaseTextarea component, here we emit an event on change event &amp;amp; emit the checked value of the element.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;That's all. You have successfully created your BaseCheckbox component and use it anywhere in the project.&lt;/p&gt;

&lt;p&gt;You can add id attribute to your checkbox component and to the label component so that user when click on the label, can check or uncheck the component.&lt;/p&gt;

&lt;p&gt;Here is the final code for this BaseCheckbox component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;template&amp;gt;
    &amp;lt;div&amp;gt;
        &amp;lt;input
            v-bind="$attrs"
            :checked="modelValue"
            @change="updateInput"
            type="checkbox"
            class="h-4 w-4 focus:ring-0 cursor-pointer rounded"
        /&amp;gt;
        &amp;lt;label :for="$attrs.id" class="ml-2 block text-sm text-gray-900 cursor-pointer"&amp;gt;
            {{label}}
        &amp;lt;/label&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/template&amp;gt;

&amp;lt;script&amp;gt;
export default {
    name: 'BaseCheckbox',
    inheritAttrs: false
}
&amp;lt;/script&amp;gt;

&amp;lt;script setup&amp;gt;
const emit = defineEmits(['update:modelValue'])

const props = defineProps({
    label: {
        type: String,
        default: ''
    },
    modelValue: {
        type: Boolean,
        default: false
    }
})

const updateInput = ($event) =&amp;gt; {
    emit('update:modelValue', $event.target.checked)
}
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check all the source code in the GitHub repo at &lt;a href="https://github.com/scriptmint-solution/vue3-tailwind-form-components"&gt;https://github.com/scriptmint-solution/vue3-tailwind-form-components&lt;/a&gt;&lt;/p&gt;

</description>
      <category>vue</category>
      <category>tailwindcss</category>
      <category>form</category>
      <category>components</category>
    </item>
    <item>
      <title>Vue3 Tailwind CSS Form Components Part II - Reusable BaseTextarea Component</title>
      <dc:creator>ScriptMint</dc:creator>
      <pubDate>Tue, 08 Feb 2022 05:02:30 +0000</pubDate>
      <link>https://dev.to/scriptmint/vue3-tailwind-css-form-components-part-i-reusable-basetextarea-component-4c21</link>
      <guid>https://dev.to/scriptmint/vue3-tailwind-css-form-components-part-i-reusable-basetextarea-component-4c21</guid>
      <description>&lt;p&gt;This is second part of &lt;a href="https://dev.to/scriptmint/series/16710"&gt;Vue3 Tailwind Form Components Series&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Form Components are very important for any Web Application. Think about a project without proper Form Components with multiple forms in it. What if you need to change design of your text input or you wish to add extra functionality into text input? I did the same mistake in 2018 when using Vue2 and still my project is not easy to maintain.&lt;/p&gt;

&lt;p&gt;Live Demo: &lt;a href="https://scriptmint-solution.github.io/vue3-tailwind-form-components/" rel="noopener noreferrer"&gt;https://scriptmint-solution.github.io/vue3-tailwind-form-components/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;GitHub Repository: &lt;a href="https://github.com/scriptmint-solution/vue3-tailwind-form-components" rel="noopener noreferrer"&gt;https://github.com/scriptmint-solution/vue3-tailwind-form-components&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Do check our Advanced Featured Admin Panel at &lt;a href="https://scriptmint.com/vana-admin" rel="noopener noreferrer"&gt;Vana Admin&lt;/a&gt; built with Laravel, Vue.js 3 &amp;amp; Tailwind CSS 3 with tons of inbuilt features to quickly build your next project.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  BaseTextarea
&lt;/h3&gt;

&lt;p&gt;Lets start with this Component:&lt;/p&gt;

&lt;p&gt;BaseTextarea will be very similar to BaseInput. BaseInput accepts single line of text input while BaseTextarea will accept multi line text input.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;BaseTextarea id="name" name="name" label="Sample Textarea" /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is the output we are expecting:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1644252323999%2FitK6IPxu1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1644252323999%2FitK6IPxu1.png" alt="image.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Lets start with a very basic textarea component. Create a BaseTextarea.vue file inside your components directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;template&amp;gt;
    &amp;lt;div&amp;gt;
        &amp;lt;textarea
            rows="3" class="w-full shadow appearance-none border rounded py-2 px-3 
            text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
        /&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/template&amp;gt;

&amp;lt;script&amp;gt;
export default {
    name: 'BaseTextarea',
    inheritAttrs: false
}
&amp;lt;/script&amp;gt;

&amp;lt;script setup&amp;gt;
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have only applied some css classes to make it look better and a row attribute. Lets add some props now. Also note that we have set inheriAttrs property to false, as we wish to bind the attributes of BaseTextarea to the input field (Not with the root element).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;script setup&amp;gt;
const props = defineProps({
    label: {
        type: String,
        default: ''
    },
    placeholder: {
        type: String,
        default: ''
    },
    modelValue: {
        type: [String, Number],
        default: ''
    }
})
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In Vue3, you can pass v-model attribute in your component and it will be available as modelValue inside your component. Also, we need to bind this modelValue to the value attribute of the input field. &lt;/p&gt;

&lt;p&gt;Next, we need to emit the value everytime whenever user input a value. To do so, we will make&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;textarea
    v-bind="$attrs"
    rows="3" class="w-full shadow appearance-none border rounded py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
    :value="modelValue"
    @input="updateInput"
/&amp;gt;
...
...

const emit = defineEmits(['update:modelValue'])

const updateInput = ($event) =&amp;gt; {
    emit('update:modelValue', $event.target.value)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we bind the attributes to the the field which emits the value of the textarea field and make it available to the BaseTextarea component v-model attribute via two way binding.&lt;/p&gt;

&lt;p&gt;That's it. You have successfully created your BaseTextarea component and use it anywhere in the project.&lt;/p&gt;

&lt;p&gt;Let's assume you need to add another functionality to add labels above your input field. You don't need to go every single textarea field but edit it only in the BaseTextarea component field.&lt;/p&gt;

&lt;p&gt;Remember we created BaseLabel component in the last article. Lets use it in your BaseTextarea component as below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;BaseLabel :for="$attrs.id"&amp;gt;{{label}}&amp;lt;/BaseLabel&amp;gt;

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

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;script setup&amp;gt;
import BaseLabel from  './BaseLabel.vue'

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

&lt;/div&gt;



&lt;p&gt;Similarly, you can help block or error message component and add it in your BaseTextarea field.&lt;/p&gt;

&lt;p&gt;Check all the source code in the GitHub repo at &lt;a href="https://github.com/scriptmint-solution/vue3-tailwind-form-components" rel="noopener noreferrer"&gt;https://github.com/scriptmint-solution/vue3-tailwind-form-components&lt;/a&gt;&lt;/p&gt;

</description>
      <category>tailwindcss</category>
      <category>form</category>
      <category>component</category>
      <category>vue</category>
    </item>
    <item>
      <title>Vue3 Tailwind CSS Form Components Part I - Reusable BaseInput Component</title>
      <dc:creator>ScriptMint</dc:creator>
      <pubDate>Mon, 07 Feb 2022 08:39:16 +0000</pubDate>
      <link>https://dev.to/scriptmint/vue3-tailwind-css-form-components-part-i-reusable-baseinput-component-gpj</link>
      <guid>https://dev.to/scriptmint/vue3-tailwind-css-form-components-part-i-reusable-baseinput-component-gpj</guid>
      <description>&lt;p&gt;This is first part of &lt;a href="https://dev.to/scriptmint/series/16710"&gt;Vue3 Tailwind Form Components Series&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Form Components are very important for any Web Application. Think about a project without proper Form Components with multiple forms in it. What if you need to change design of your text input or you wish to add extra functionality into text input? I did the same mistake in 2018 when using Vue2 and still my project is not easy to maintain.&lt;/p&gt;

&lt;p&gt;Live Demo: &lt;a href="https://scriptmint-solution.github.io/vue3-tailwind-form-components/" rel="noopener noreferrer"&gt;https://scriptmint-solution.github.io/vue3-tailwind-form-components/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;GitHub Repository: &lt;a href="https://github.com/scriptmint-solution/vue3-tailwind-form-components" rel="noopener noreferrer"&gt;https://github.com/scriptmint-solution/vue3-tailwind-form-components&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Do check our Advanced Featured Admin Panel at &lt;a href="https://scriptmint.com/vana-admin" rel="noopener noreferrer"&gt;Vana Admin&lt;/a&gt; built with Laravel, Vue.js 3 &amp;amp; Tailwind CSS 3 with tons of inbuilt features to quickly build your next project.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the first article of this series, we are going to create a Form Component:&lt;/p&gt;

&lt;h3&gt;
  
  
  BaseInput
&lt;/h3&gt;

&lt;p&gt;Lets start with this Component:&lt;/p&gt;

&lt;p&gt;Every text input either comes with a Label. It may accompany a Help block or Error message, keeping all these mind, here is what we are trying to achieve.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;BaseInput id="name" name="name" type="text" label="Sample Input with Help" /&amp;gt;
&amp;lt;HelpBlock&amp;gt;This is a help block!&amp;lt;/HelpBlock&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is the output we are expecting:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1644217332835%2FTUle6Ti6v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1644217332835%2FTUle6Ti6v.png" alt="image.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Lets start with a very basic input component. Create a BaseInput.vue file inside your components directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;template&amp;gt;
    &amp;lt;div&amp;gt;
        &amp;lt;input
            class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
        /&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/template&amp;gt;

&amp;lt;script&amp;gt;
export default {
    name: 'BaseInput',
    inheritAttrs: false
}
&amp;lt;/script&amp;gt;

&amp;lt;script setup&amp;gt;
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have only applied some css classes to make it look better. Lets add some props now. Also note that we have set inheriAttrs property to false, as we wish to bind the attributes of BaseInput to the input field (Not with the root element).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;script setup&amp;gt;
const props = defineProps({
    label: {
        type: String,
        default: ''
    },
    placeholder: {
        type: String,
        default: ''
    },
    modelValue: {
        type: [String, Number],
        default: ''
    }
})
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In Vue3, you can pass v-model attribute in your component and it will be available as modelValue inside your component. Also, we need to bind this modelValue to the value attribute of the input field. &lt;/p&gt;

&lt;p&gt;Next, we need to emit the value everytime whenever user input a value. To do so, we will make&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;input
    v-bind="$attrs"
    class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
    :value="modelValue"
    @input="updateInput"
/&amp;gt;
...
...

const emit = defineEmits(['update:modelValue'])

const updateInput = ($event) =&amp;gt; {
    emit('update:modelValue', $event.target.value)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, wee bind the attributes to the input field which emits the value of the input field and make it available to the BaseInput component v-model attribute via two way binding.&lt;/p&gt;

&lt;p&gt;That's it. You have successfully created your BaseInput component and use it anywhere in the project.&lt;/p&gt;

&lt;p&gt;Let's assume you need to add another functionality to add labels above your input field. You don't need to go every single input field but edit it only in the BaseInput component field.&lt;/p&gt;

&lt;p&gt;Create another BaseLabel.vue file inside your components directory and put below code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;template&amp;gt;
    &amp;lt;label :for="for" class="block text-sm font-medium text-label text-gray-800 dark:text-gray-300 truncate"&amp;gt;
        &amp;lt;slot&amp;gt;&amp;lt;/slot&amp;gt;
    &amp;lt;/label&amp;gt;
&amp;lt;/template&amp;gt;

&amp;lt;script&amp;gt;
export default {
    name: 'BaseLabel'
}
&amp;lt;/script&amp;gt;

&amp;lt;script setup&amp;gt;
const props = defineProps({
    for: {
        type: String,
        default: ''
    }
})
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we are accepting for attribute that will use to bind this label with the input field. Next, use it in your BaseInput component as below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;BaseLabel :for="$attrs.id"&amp;gt;{{label}}&amp;lt;/BaseLabel&amp;gt;

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

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;script setup&amp;gt;
import BaseLabel from  './BaseLabel.vue'

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

&lt;/div&gt;



&lt;p&gt;Simple it is. Right? Similarly, you can help block or error message component and add it in your BaseInput field.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bonus
&lt;/h3&gt;

&lt;p&gt;Add success, error, info &amp;amp; warning class to make your component feature reach.&lt;/p&gt;

&lt;p&gt;Check all the source code in the GitHub repo at &lt;a href="https://github.com/scriptmint-solution/vue3-tailwind-form-components" rel="noopener noreferrer"&gt;https://github.com/scriptmint-solution/vue3-tailwind-form-components&lt;/a&gt;&lt;/p&gt;

</description>
      <category>vue</category>
      <category>tailwindcss</category>
      <category>form</category>
      <category>components</category>
    </item>
    <item>
      <title>Vumin - Free Vue.js, Tailwind CSS Admin Template</title>
      <dc:creator>ScriptMint</dc:creator>
      <pubDate>Sun, 06 Feb 2022 07:13:54 +0000</pubDate>
      <link>https://dev.to/scriptmint/vumin-free-vuejs-tailwind-css-admin-template-23a4</link>
      <guid>https://dev.to/scriptmint/vumin-free-vuejs-tailwind-css-admin-template-23a4</guid>
      <description>&lt;h3&gt;
  
  
  Vumin is a Free Admin Template built with Vue.js &amp;amp; Tailwind CSS.
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Highlights
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;SPA (Single Page Application)&lt;/li&gt;
&lt;li&gt;Reusable Components&lt;/li&gt;
&lt;li&gt;Vue Router &amp;amp; VueX Support&lt;/li&gt;
&lt;li&gt;Compsition API&lt;/li&gt;
&lt;li&gt;Script Setup Syntax&lt;/li&gt;
&lt;li&gt;Super Fast Vite.js builds within 10 seconds&lt;/li&gt;
&lt;li&gt;Production CSS &amp;lt; 20 kb, JS &amp;lt; 200 kb&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Live Demo: &lt;a href="https://vumin.scriptmint.com" rel="noopener noreferrer"&gt;https://vumin.scriptmint.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;GitHub Repository: &lt;a href="https://github.com/scriptmint-solution/vumin-lite" rel="noopener noreferrer"&gt;https://github.com/scriptmint-solution/vumin-lite&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Advance and Full Featured Admin Panel built with Laravel, Vue.js &amp;amp; Tailwind CSS is available.&lt;br&gt;
Live Demo of Advance Version: &lt;a href="https://ui.scriptmint.com" rel="noopener noreferrer"&gt;https://ui.scriptmint.com&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Features Available
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Mobile Responsive&lt;/li&gt;
&lt;li&gt;Dark &amp;amp; Light Mode&lt;/li&gt;
&lt;li&gt;Profile Dropdown&lt;/li&gt;
&lt;li&gt;Sidebar Navigation&lt;/li&gt;
&lt;li&gt;Login Page&lt;/li&gt;
&lt;li&gt;Register Page&lt;/li&gt;
&lt;li&gt;Password Page&lt;/li&gt;
&lt;li&gt;Dashboard with Chart &amp;amp; Stats&lt;/li&gt;
&lt;li&gt;Sample Table&lt;/li&gt;
&lt;li&gt;Sample Form&lt;/li&gt;
&lt;li&gt;Sample Cards&lt;/li&gt;
&lt;li&gt;404 Error&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1644129450770%2FbJhmku7PI.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1644129450770%2FbJhmku7PI.png" alt="light-dark-mode-min.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1644129459013%2FVxzkpjIEH.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1644129459013%2FVxzkpjIEH.png" alt="mobile-layout-min.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1644129464520%2Fe84RggkEY.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1644129464520%2Fe84RggkEY.png" alt="other-pages-min.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Installation
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone git@github.com:scriptmint-solution/vumin-lite.git vumin
cd vumin
npm install
npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  NPM packages used:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Font Awesome&lt;/li&gt;
&lt;li&gt;HeadlessUI&lt;/li&gt;
&lt;li&gt;Chart.js&lt;/li&gt;
&lt;li&gt;Vue&lt;/li&gt;
&lt;li&gt;Vue Router&lt;/li&gt;
&lt;li&gt;VueX&lt;/li&gt;
&lt;li&gt;TailwindCSS&lt;/li&gt;
&lt;li&gt;TailwindCSS Form&lt;/li&gt;
&lt;li&gt;Vite.js&lt;/li&gt;
&lt;li&gt;Vite.js Compression Plugin&lt;/li&gt;
&lt;li&gt;PostCSS&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Browser Support
&lt;/h4&gt;

&lt;p&gt;Modern Browser Only&lt;/p&gt;

&lt;h4&gt;
  
  
  Issue Reporting
&lt;/h4&gt;

&lt;p&gt;If you face any issue, please raise issue at &lt;a href="https://github.com/scriptmint-solution/vumin-lite/issues" rel="noopener noreferrer"&gt;https://github.com/scriptmint-solution/vumin-lite/issues&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  License
&lt;/h4&gt;

&lt;p&gt;MIT License &lt;br&gt;
Copyright (c) 2022 scriptmint.com (&lt;a href="https://scriptmint.com" rel="noopener noreferrer"&gt;https://scriptmint.com&lt;/a&gt;)&lt;/p&gt;

</description>
      <category>vue</category>
      <category>tailwindcss</category>
      <category>template</category>
      <category>free</category>
    </item>
    <item>
      <title>My MacBook Setup for Development!</title>
      <dc:creator>ScriptMint</dc:creator>
      <pubDate>Sat, 05 Feb 2022 04:34:28 +0000</pubDate>
      <link>https://dev.to/scriptmint/my-macbook-setup-for-development-3088</link>
      <guid>https://dev.to/scriptmint/my-macbook-setup-for-development-3088</guid>
      <description>&lt;h3&gt;
  
  
  How I setup MacBook, What Apps do I use to improve productivity?
&lt;/h3&gt;

&lt;p&gt;I usually share articles about coding but today I decided to share an article about my MacBook &amp;amp; Dev Environment setup. &lt;/p&gt;

&lt;p&gt;I am using 16 Inch MacBook Pro 2019 Model and quite satisfied with its performance since last 2 years.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1643995339230%2F2KG1DuOLW.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1643995339230%2F2KG1DuOLW.png" alt="MacBook Model.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I don't restart my MacBook regularly until it gets started slowing down. At this time of writing, I found that last restart was around a month ago (Yes! It's been 31 days) and not a single sign of slow down. Truly worth buying!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1643994975554%2F6zgWCs96s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1643994975554%2F6zgWCs96s.png" alt="image.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;MacBook is my second ❤️. Obviously Family is the first. But I use to treat MacBook same as my Family Member. All the files &amp;amp; folders are arranged in very systematically that I don't need to use the search bar any more.&lt;/p&gt;

&lt;p&gt;My Desktop &amp;amp; Download Folder is always empty! Everytime, I download a file and either I delete it after use or move it to folders of its type.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1644030681326%2Fif5q6fW4L.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1644030681326%2Fif5q6fW4L.png" alt="Desktop &amp;amp; Download-min.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I know it is not an easy task, I have seen garbage on many other's computer. I even keep emptying my trash items. Is it too much?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/sUzZwE9AgI8iA/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/sUzZwE9AgI8iA/giphy.gif" alt="Angry"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Okay! Coming back to the point.&lt;/p&gt;

&lt;p&gt;I have replaced spotlight with &lt;a href="https://www.raycast.com/" rel="noopener noreferrer"&gt;RayCast&lt;/a&gt; and believe me it is amazing. It offers tons of extra features like snippets, extensions etc that I am using frequently since last 2 months.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1644033769480%2FywO-XLaXb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1644033769480%2FywO-XLaXb.png" alt="image.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I am a Full Stack Developer working with &lt;a href="https://laravel.com" rel="noopener noreferrer"&gt;Laravel&lt;/a&gt;, &lt;a href="https://vuejs.org" rel="noopener noreferrer"&gt;VueJS&lt;/a&gt;, &lt;a href="https://tailwindcss.com" rel="noopener noreferrer"&gt;Tailwind CSS&lt;/a&gt;. I use to have all my windows in a fixed order. This helps me to improve my productivity multi-fold. Let me show you how!&lt;/p&gt;

&lt;p&gt;Usually I have 7 windows with Desktop arranged in centre. Here is the order from left to right:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1644032446087%2F8kM8dqzet.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1644032446087%2F8kM8dqzet.png" alt="Windows.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Most of my time is spent around iTerm2 &amp;amp; VS Code that is why it is positioned centred.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://sparkmailapp.com" rel="noopener noreferrer"&gt;Spark Email&lt;/a&gt; &amp;amp; &lt;a href="https://todoist.com" rel="noopener noreferrer"&gt;Todoist&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;I use to manage multiple emails. Spark is one of the best email client I found for MacOS. I have merged this window with Todoist and you know it doesn't look like two different app. Check the screenshot!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1644031894599%2F7aLctk7ks.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1644031894599%2F7aLctk7ks.png" alt="Spark &amp;amp; Todoist-min.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I use Todoist as my Calendar with all my tasks listed in it and I am a Pro-user of Todoist.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://evernote.com/" rel="noopener noreferrer"&gt;Evernote&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;It is my life saver. I use to put all my notes, memo in it. It takes full window size and pretty useful for user like me. Again, I am using paid version of it, to use premium features &amp;amp; make my time it more productive. Btw, I have over 24 Notebooks on Evernote.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1644032295348%2FT6fPZSod4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1644032295348%2FT6fPZSod4.png" alt="Evernote-min.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://desktop.github.com/" rel="noopener noreferrer"&gt;GitHub Desktop&lt;/a&gt; &amp;amp; &lt;a href="https://sequel-ace.com/" rel="noopener noreferrer"&gt;Sequel Ace&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;GitHub is another life saver for developers. Sequel Ace is my Database Management tool. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1644032713139%2FsE5Eal1R3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1644032713139%2FsE5Eal1R3.png" alt="GitHub &amp;amp; Sequel Ace-min.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Desktop
&lt;/h3&gt;

&lt;p&gt;Desktop is in the centre of stage with iTerm2 &amp;amp; Finder sharing half each.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1644032873812%2F6tOj6J52x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1644032873812%2F6tOj6J52x.png" alt="Desktop-min.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://code.visualstudio.com/" rel="noopener noreferrer"&gt;VS Code&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;I spent most of my development time with VS Code. Started using it in 2017 after watching &lt;a href="https://laracasts.com/" rel="noopener noreferrer"&gt;Jeffrey Way's&lt;/a&gt; tutorial &lt;a href="https://laracasts.com/series/visual-studio-code-for-php-developers" rel="noopener noreferrer"&gt;https://laracasts.com/series/visual-studio-code-for-php-developers&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My VS Code setup is very much inspired by Caleb Porzio's &lt;a href="https://makevscodeawesome.com" rel="noopener noreferrer"&gt;https://makevscodeawesome.com&lt;/a&gt;. I can write a separate article about VS Code setup.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1644033315624%2FrQTC-p3dT.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1644033315624%2FrQTC-p3dT.png" alt="VS Code-min.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Google Chrome
&lt;/h3&gt;

&lt;p&gt;Don't think, I have to say much about it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1644033420552%2Fx2mfrZcfS.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1644033420552%2Fx2mfrZcfS.png" alt="Chrome-min.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://termius.com/" rel="noopener noreferrer"&gt;Termius&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Termius is an SSH Client which I find the best. Everything offered by Termium is awesome and I use it regularly. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1644033467389%2FwKS0-pm4u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1644033467389%2FwKS0-pm4u.png" alt="Termius-min.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This fixed order helps me to save a lot of my time. My fingers move left to right and vice versa quickly without any confusion. &lt;/p&gt;

&lt;p&gt;Here are the other Apps I use on my MacBook for Development Purpose:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;iTerm2 with zsh &amp;amp; using &lt;a href="https://ohmyz.sh/" rel="noopener noreferrer"&gt;Oh My Zsh!&lt;/a&gt; for a delightful terminal experience - Will write a separate article about it.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://tinkerwell.app/" rel="noopener noreferrer"&gt;Tinkerwell&lt;/a&gt; by &lt;a href="https://beyondco.de/" rel="noopener noreferrer"&gt;BeyondCode&lt;/a&gt; - Must have PHP Dev tool for every Laravel Developer&lt;/li&gt;
&lt;li&gt;Invoker by &lt;a href="https://beyondco.de/" rel="noopener noreferrer"&gt;BeyondCode&lt;/a&gt; - Another amazing tool for Laravel Developers&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://usehelo.com" rel="noopener noreferrer"&gt;Hello&lt;/a&gt; by &lt;a href="https://beyondco.de/" rel="noopener noreferrer"&gt;BeyondCode&lt;/a&gt; - Local Email testing tool&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://spatie.be/products/ray" rel="noopener noreferrer"&gt;Ray&lt;/a&gt; by &lt;a href="https://spatie.be/" rel="noopener noreferrer"&gt;Spatie&lt;/a&gt; - Debugger tool&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://postman.com" rel="noopener noreferrer"&gt;Postman&lt;/a&gt; - API client&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.sublimetext.com" rel="noopener noreferrer"&gt;Sublime Text&lt;/a&gt; - Not as much as VS Code but it is also a life saver.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I fall in ❤️ with my MacBook every day I start my work with this beautiful setup &amp;amp; I have improved my productivity a lot.&lt;/p&gt;

&lt;p&gt;You can see that I am a Big fan of Dark Mode. Almost every thing on my MacBook &amp;amp; iPhone will have Dark Mode.&lt;/p&gt;

&lt;p&gt;In my free time, my favorite google search is "Productivity Tools for MacOS".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/XDYHnoWtNU7mHoVhTM/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/XDYHnoWtNU7mHoVhTM/giphy.gif" alt="Mad"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Do share how you setup &amp;amp; use your computer. Lets learn from sharing and make coding awesome!&lt;/p&gt;

</description>
      <category>macbook</category>
      <category>macos</category>
      <category>development</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Multicolor theme &amp; Dark Mode setup with Tailwind CSS</title>
      <dc:creator>ScriptMint</dc:creator>
      <pubDate>Fri, 04 Feb 2022 10:44:19 +0000</pubDate>
      <link>https://dev.to/scriptmint/multicolor-theme-setup-with-tailwind-css-1odd</link>
      <guid>https://dev.to/scriptmint/multicolor-theme-setup-with-tailwind-css-1odd</guid>
      <description>&lt;p&gt;&lt;a href="https://tailwindcss.com"&gt;Tailwind CSS&lt;/a&gt; offers out of the box support for theming your project. With Tailwind CSS, you can offer multicolor theme feature in your project with few lines of code.&lt;/p&gt;

&lt;p&gt;Live Demo: &lt;a href="https://scriptmint.github.io/tailwind-theme/"&gt;https://scriptmint.github.io/tailwind-theme/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Github Repo: &lt;a href="https://github.com/scriptmint/tailwind-theme"&gt;https://github.com/scriptmint/tailwind-theme&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So lets setup a Multicolor Theme project with Tailwind CSS. Open your terminal &amp;amp; start working.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir tailwind-theme
cd tailwind-theme
npm install -D tailwindcss
npx tailwindcss init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will generate a tailwind.config.js file in your directory. Lets make little modification here.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module.exports = {
  content: ["./*.{html,js}"],
  theme: {
    extend: {},
  },
  plugins: [],
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we are defining the directory &amp;amp; its files where we will write some CSS classes and all other unused classes which are generated in the Tailwind CSS will be purged.&lt;/p&gt;

&lt;p&gt;Next, lets create a css file /src/app.css.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@tailwind base;
@tailwind components;

.theme-first {
    --color-primary: #1e293b;
    --color-secondary: #e2e8f0;
}

.theme-second {
    --color-primary: #991b1b;
    --color-secondary: #fecaca;
}

.theme-third {
    --color-primary: #166534;
    --color-secondary: #bbf7d0;
}

@tailwind utilities;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have setup three themes with primary &amp;amp; secondary color along with default tailwind setup.&lt;/p&gt;

&lt;p&gt;We will need to configure our tailwind.config.js file again as below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const colors = require('tailwindcss/colors')

module.exports = {
  content: ["./*.{html,js}"],
  theme: {
    textColor: {
      "primary" : "var(--color-primary)",
      "secondary" : "var(--color-secondary)",
        ...colors
    },
    backgroundColor: {
      "primary" : "var(--color-primary)",
      "secondary" : "var(--color-secondary)",
        ...colors
    },
    extend: {},
  },
  plugins: [],
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will generate "text-primary", "text-secondary", "bg-primary" &amp;amp; "bg-secondary" class with given theme color.&lt;/p&gt;

&lt;p&gt;As mentioned earlier, Tailwind CSS offers out of the box support for themes. We are defining text &amp;amp; background colors which will be picked up based on the current theme.&lt;/p&gt;

&lt;p&gt;So, its time to create your html file to so the Tailwind magic:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang="en"&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;meta charset="UTF-8" /&amp;gt;
    &amp;lt;link rel="icon" href="https://scriptmint.com/images/favicons/favicon.ico" /&amp;gt;
    &amp;lt;meta name="viewport" content="width=device-width, initial-scale=1.0" /&amp;gt;
    &amp;lt;title&amp;gt;Tailwind Theme CSS&amp;lt;/title&amp;gt;
    &amp;lt;link href="/dist/app.css" rel="stylesheet"&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body class="theme-first"&amp;gt;
    &amp;lt;div class="h-screen w-full flex items-center justify-center bg-primary"&amp;gt;
      &amp;lt;div class="space-y-4"&amp;gt;
        &amp;lt;h1 class="text-secondary text-center"&amp;gt;Hello World!&amp;lt;/h1&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we are adding "theme-first" class on the body element. You can change this class to "theme-second" or "theme-third" to get the desired color theme.&lt;/p&gt;

&lt;p&gt;Next, lets build our CSS file using below command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx tailwindcss -i ./src/app.css -o ./dist/app.css
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will generate your css file under "dist" directory. Link this css file in our HTML directory and visit on your browser.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bonus - Dark Theme Setup
&lt;/h3&gt;

&lt;p&gt;You need not to add another theme to offer dark theme in your project. You can add one line in the tailwind.config.js file as below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module.exports = {
  content: ["./*.{html,js}"],
  darkMode: 'class',
  theme: {
  ...
  ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we are defining darkMode property to "class". Now, you can put "dark" class in the body element to get the desired result. Also, you can now define the dark theme color using "dark:" modifier like we added "dark:bg-gray-800" class.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang="en"&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;meta charset="UTF-8" /&amp;gt;
    &amp;lt;link rel="icon" href="https://scriptmint.com/images/favicons/favicon.ico" /&amp;gt;
    &amp;lt;meta name="viewport" content="width=device-width, initial-scale=1.0" /&amp;gt;
    &amp;lt;title&amp;gt;Tailwind Theme CSS&amp;lt;/title&amp;gt;
    &amp;lt;link href="/dist/app.css" rel="stylesheet"&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body class="theme-first"&amp;gt;
    &amp;lt;div class="h-screen w-full flex items-center justify-center bg-primary dark:bg-gray-800"&amp;gt;
      &amp;lt;div class="space-y-4"&amp;gt;
        &amp;lt;h1 class="text-secondary dark:text-gray-200 text-center"&amp;gt;Hello World!&amp;lt;/h1&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tailwind offers various configurations which you can even use to change fonts, borders, radius etc with this theme configuration. You can read more about Tailwind CSS theme at &lt;a href="https://tailwindcss.com/docs/theme"&gt;https://tailwindcss.com/docs/theme&lt;/a&gt;&lt;/p&gt;

</description>
      <category>tailwindcss</category>
      <category>theme</category>
    </item>
    <item>
      <title>Set up Tailwind, AlpineJS, Laravel &amp; Livewire - TALL Stack for Development</title>
      <dc:creator>ScriptMint</dc:creator>
      <pubDate>Wed, 02 Feb 2022 19:56:45 +0000</pubDate>
      <link>https://dev.to/scriptmint/set-up-tailwind-alpinejs-laravel-livewire-tall-stack-for-development-1a5d</link>
      <guid>https://dev.to/scriptmint/set-up-tailwind-alpinejs-laravel-livewire-tall-stack-for-development-1a5d</guid>
      <description>&lt;p&gt;&lt;em&gt;Note: You should have basic knowledge of Laravel, NPM commands before you setup this TALL Stack.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://tallstack.dev" rel="noopener noreferrer"&gt;TALL&lt;/a&gt; is another popular dev stack in Laravel Community. I personally choose TALL Stack when I need to build small size Web Application without any REST API Feature.&lt;/p&gt;

&lt;p&gt;Github Repo: &lt;a href="https://github.com/scriptmint-solution/tall-stack-setup" rel="noopener noreferrer"&gt;https://github.com/scriptmint-solution/tall-stack-setup&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here are the steps I prefer to setup TALL Stack.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setup Laravel 8
&lt;/h3&gt;

&lt;p&gt;You must have Composer v2 installed on your system. &lt;/p&gt;

&lt;p&gt;If you wish to install Laravel with Composer, you can run:&lt;/p&gt;

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

composer create-project laravel/laravel vutal
cd vutal


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

&lt;/div&gt;

&lt;p&gt;Or&lt;/p&gt;

&lt;p&gt;If you have installed Laravel Installer globally as composer dependency, you can run:&lt;/p&gt;

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

laravel new vutal
cd vutal


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

&lt;/div&gt;
&lt;h3&gt;
  
  
  Install Laravel Livewire
&lt;/h3&gt;

&lt;p&gt;To install Laravel Livewire, run below command:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

composer require livewire/livewire


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

&lt;/div&gt;

&lt;p&gt;You will also need to link Livewire's asset but we will come back to this step later.&lt;/p&gt;

&lt;h3&gt;
  
  
  Add Tailwind CSS 3
&lt;/h3&gt;

&lt;p&gt;To install Tailwind CSS 3, you can run:&lt;/p&gt;

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

npm install -D tailwindcss
npx tailwindcss init


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

&lt;/div&gt;

&lt;p&gt;This will create tailwind.config.js file which you can use to configure your tailwind setup. The default content of tailwind.config.js is as below:&lt;/p&gt;

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

module.exports = {
  content: [
    './resources/**/*.blade.php',
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}



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

&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Note: We are searching for all blade.php files and removing unused classes to reduce the size of your css file.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Next, create an app.scss file under resources/sass folder and put following content:&lt;/p&gt;

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

@tailwind base;
@tailwind components;
@tailwind utilities;


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

&lt;/div&gt;

&lt;p&gt;You also need to install additional dependencies by running below command:&lt;/p&gt;

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

npm install resolve-url-loader sass sass-loader --save-dev


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

&lt;/div&gt;
&lt;h3&gt;
  
  
  Add AlpineJS
&lt;/h3&gt;

&lt;p&gt;There are two ways you can add AlpineJS in your project. First one is using CDN (I rarely use it). I use to go with second one as following:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

npm install alpinejs


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

&lt;/div&gt;

&lt;p&gt;Next, edit your resources/js/app.js file and import AlpineJS as below:&lt;/p&gt;

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

import Alpine from 'alpinejs'

window.Alpine = Alpine
Alpine.start()


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

&lt;/div&gt;

&lt;p&gt;We will see its magic in a few moments.&lt;/p&gt;

&lt;p&gt;Now, edit your webpack.mix.js file that will compile your assets.&lt;/p&gt;

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

const mix = require('laravel-mix');
const tailwindcss = require('tailwindcss');

mix.js('resources/js/app.js', 'public/js')
    .sass('resources/sass/app.scss', 'public/css')
    .options({
        postCss: [ tailwindcss('./tailwind.config.js') ],
    });


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

&lt;/div&gt;

&lt;p&gt;Also, build your assets using npm command:&lt;/p&gt;

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

npm run dev


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

&lt;/div&gt;

&lt;p&gt;The assets are generated under public folder as shown in the image below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1643800393963%2F4Lh7Ra7DE.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1643800393963%2F4Lh7Ra7DE.png" alt="image.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can link these assets to your welcome.blade.php file as below.&lt;/p&gt;

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

&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang="en"&amp;gt;
    &amp;lt;head&amp;gt;
        &amp;lt;meta charset="utf-8"&amp;gt;
        &amp;lt;meta http-equiv="X-UA-Compatible" content="IE=edge"&amp;gt;
        &amp;lt;meta name="viewport" content="width=device-width, initial-scale=1"&amp;gt;
        &amp;lt;title&amp;gt;Hello World&amp;lt;/title&amp;gt;
        &amp;lt;link href="/css/app.css" rel="stylesheet"&amp;gt;
        @livewireStyles
    &amp;lt;/head&amp;gt;
    &amp;lt;body&amp;gt;

        &amp;lt;div class="h-screen w-full flex justify-center items-center bg-gray-800"&amp;gt;
            &amp;lt;!-- Livewire component will be placed here --&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;script src="/js/app.js"&amp;gt;&amp;lt;/script&amp;gt;
        @livewireScripts
    &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;


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

&lt;/div&gt;

&lt;p&gt;Note that we also added Livewire assets in our blade file and also put some Tailwind styling.&lt;/p&gt;

&lt;p&gt;Your TALL Stack setup is now completed. Its time to add your first Livewire component, run below command to create a Livewire component:&lt;/p&gt;

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

php artisan make:livewire counter


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

&lt;/div&gt;

&lt;p&gt;This will generate Counter.php file under app/Http/Livewire directory &amp;amp; a counter.blade.php file under resources/views/livewire directory.&lt;/p&gt;

&lt;p&gt;Edit counter.blade.php file and put some Livewire magic over there.&lt;/p&gt;

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

&amp;lt;div class="space-x-4"&amp;gt;
    &amp;lt;button class="bg-gray-300 px-4 py-2 rounded text-gray-700" wire:click="increment"&amp;gt;Increment&amp;lt;/button&amp;gt;
    &amp;lt;button class="bg-gray-300 px-4 py-2 rounded text-gray-700" wire:click="decrement"&amp;gt;Decrement&amp;lt;/button&amp;gt;

    &amp;lt;div class="block py-4 text-gray-300 text-center"&amp;gt;{{$count}}&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;


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

&lt;/div&gt;

&lt;p&gt;We are generating two buttons to to change the counter value. The increment &amp;amp; decrement functions are defined in Counter.php file as below:&lt;/p&gt;

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

&amp;lt;?php

namespace App\Http\Livewire;

use Livewire\Component;

class Counter extends Component
{
    public $count = 0;

    public function increment()
    {
        $this-&amp;gt;count++;
    }

    public function decrement()
    {
        $this-&amp;gt;count--;
    }

    public function render()
    {
        return view('livewire.counter');
    }
}


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

&lt;/div&gt;

&lt;p&gt;Your Livewire component is ready, add it in your welcome.blade.php file as below:&lt;/p&gt;

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

&amp;lt;div class="h-screen w-full flex justify-center items-center bg-gray-800"&amp;gt;
    @livewire('counter')
&amp;lt;/div&amp;gt;


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

&lt;/div&gt;

&lt;p&gt;Now, compile the assets once again &amp;amp; navigate to your application in your browser.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1643830098730%2Fj3MMCwvFJ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1643830098730%2Fj3MMCwvFJ.png" alt="image.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;See the Livewire magic yourself. You can increment or decrement counter's value without any page refresh.&lt;/p&gt;

&lt;p&gt;Lets see the magic of AlpineJS. Add another button toggle in counter.blade.php file to show &amp;amp; hide the counter.&lt;/p&gt;

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

&amp;lt;div class="space-y-4" x-data="{show: true}"&amp;gt;
    &amp;lt;button class="bg-blue-300 px-4 py-2 rounded text-blue-700" @click="show = ! show"&amp;gt;Toggle&amp;lt;/button&amp;gt;

    &amp;lt;div class="space-x-4" x-show="show"&amp;gt;
        &amp;lt;button class="bg-gray-300 px-4 py-2 rounded text-gray-700" wire:click="increment"&amp;gt;Increment&amp;lt;/button&amp;gt;
        &amp;lt;button class="bg-gray-300 px-4 py-2 rounded text-gray-700" wire:click="decrement"&amp;gt;Decrement&amp;lt;/button&amp;gt;

        &amp;lt;div class="block py-4 text-gray-300 text-center"&amp;gt;{{$count}}&amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;


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

&lt;/div&gt;

&lt;p&gt;Refresh the page &amp;amp; see the magic of AlpineJS. You can toggle the visibility of counter buttons with minimal 3 lines of AlpineJS code.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1643830447883%2FUTlbzz3u2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1643830447883%2FUTlbzz3u2.png" alt="image.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I hope you like this post. If you have any query, please comment.&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>tailwindcss</category>
      <category>livewire</category>
      <category>alpinejs</category>
    </item>
  </channel>
</rss>
