<?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: Lâm Kim Phú</title>
    <description>The latest articles on DEV Community by Lâm Kim Phú (@lkp).</description>
    <link>https://dev.to/lkp</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%2F807538%2F40a09f4d-c9c9-49a9-8d01-2e19f1c8e62b.jpeg</url>
      <title>DEV Community: Lâm Kim Phú</title>
      <link>https://dev.to/lkp</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/lkp"/>
    <language>en</language>
    <item>
      <title>Nextjs: Introduction</title>
      <dc:creator>Lâm Kim Phú</dc:creator>
      <pubDate>Thu, 02 Feb 2023 01:41:03 +0000</pubDate>
      <link>https://dev.to/lkp/nextjs-introduction-hej</link>
      <guid>https://dev.to/lkp/nextjs-introduction-hej</guid>
      <description>&lt;h2&gt;
  
  
  What is Nextjs?
&lt;/h2&gt;

&lt;p&gt;Acorrding to the official documentation, Next.js is a flexible React framework that gives you building blocks to create fast web applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Nextjs?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Difference rendering techniques
&lt;/h3&gt;

&lt;p&gt;Server Side Rendering is technique when you want to get new data from server, client will pass necessary params to server and get the whole html from server. With this approach, our app is not reactive. When you search something, filter something, click something, it will reload the whole html. It is not very friendly when you have a lot of data and user need to spend time to look at blank screen while your site is loading data. But it is good for SEO cause it always return html and google bot know what is your site about. &lt;/p&gt;

&lt;p&gt;Client Side Rendering is technique when you pass params to server from client, you will get data in json format from server. For that reason, you will save your bandwidth, your page will load faster and it will be more reactive. Nowadays, good frameworks like React, Vue, Angular do these things really well. It also handle or at least, give you a tool or a clear guide transpile to work with old browser, bundling, minifying, splitting. It will make your app faster and more compatible. However, big disadvantage in this approach is that it is hard to SEO. Why? When you load a page, in React case, you only have an html element with id is root, after that React will handle to render the rest. And google bot just see the html element before React render the rest so it only see your page have an html element with id is root. For that reason, it have no idea what is your site about and lower your page rank.&lt;/p&gt;

&lt;p&gt;Static Site Generation is technique to generate html file in build time. For example, you finish to implement your about page, you build your project, it will generate html file of about page and store in your project. So when user want to view your about page, the site will return that file instead of calling data from server. Then, it will much faster. It is very good if you don't have many changes for your page. Like about page, login page, landing page,... you won't often change or don't often have a new data so these pages is good to use SSG. &lt;/p&gt;

&lt;p&gt;Usually, you don't have all these technique in your application cause no framework support all these rendering technique yet until Nextjs. Before Nextjs, if you want SSR, you may go with pure PHP, Laravel + Blade or Symfony + Twig. If you want CSR, definitely go with React, Vue or Angular and SSG will a place where you want to use gatsby. In Nextjs, you can choose the rendering technique you want. Thus, you can have page A with SSR, page B with CSR, page C with SSG. How cool is that?&lt;/p&gt;

&lt;h3&gt;
  
  
  Performance
&lt;/h3&gt;

&lt;p&gt;To boost your site faster, you need to care about many things like code splitting, minifying files, image optimaztion, the way to get assets and many more. Thankfully, with Nextjs, you don't need to care much about this. If you use correct component which are provide by Nextjs, it will do all the heavy job for you. Small example is that when you have an image on your site, you need to take care very 2 basic things. First of all, you need to have difference size of that image for difference viewport. Secondly, you want your page only load that image when user near to it, so you will have very long page and of course, you don't want to load image at the end of that page where user don't see it when the page is loaded. When user scroll down near to the end, that image will be load. Therefore, to solve these two problems, you need add srcset and apply lazy load to your image. With simple component &lt;code&gt;Image&lt;/code&gt;, it handle these two things automatically.&lt;/p&gt;

&lt;h3&gt;
  
  
  Routing
&lt;/h3&gt;

&lt;p&gt;In Nextjs, it route base on file. In my opinion, it is more friendly for routing base on file. In case I want to find component for route &lt;code&gt;/posts/&lt;/code&gt;, I can easily know that I need to go to index file in posts folder. No need to go to see which component is used for that route.&lt;/p&gt;

&lt;h3&gt;
  
  
  SEO
&lt;/h3&gt;

&lt;p&gt;Nextjs provide a Head component. With this component, you can always add description, title, meta tag on header in Nextjs. For that reason, it will be better for SEO.&lt;/p&gt;

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

&lt;p&gt;That's is a short introduction to nextjs. In recap, it provides us many ways to render page, help we improve performance, routing base on file, provide us a way to SEO and much more.&lt;/p&gt;

</description>
      <category>cryptocurrency</category>
      <category>web3</category>
      <category>blockchain</category>
    </item>
    <item>
      <title>Multiple authentication in Laravel 9</title>
      <dc:creator>Lâm Kim Phú</dc:creator>
      <pubDate>Mon, 16 Jan 2023 01:46:52 +0000</pubDate>
      <link>https://dev.to/lkp/multiple-authentication-in-laravel-9-2mfk</link>
      <guid>https://dev.to/lkp/multiple-authentication-in-laravel-9-2mfk</guid>
      <description>&lt;h2&gt;
  
  
  Problem
&lt;/h2&gt;

&lt;p&gt;In a basic web app, we usually have two parts, app and cms. App is for user to use and cms for staff to manage content in that system. So to design this web app, we need to have a role. User with role admin can access cms site and user without role admin cannot access cms. But what if you want to use 2 difference models for security, for performance? How can we authenticate with 2 difference models?&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduce app
&lt;/h2&gt;

&lt;p&gt;This is a web app have two parts, app and CMS. Model Staff can only access CMS part and model User can only access app part. Since Laravel have default guard authentication for User model, we will discuss more about Staff model&lt;/p&gt;

&lt;h2&gt;
  
  
  Configure guard
&lt;/h2&gt;

&lt;p&gt;First of all, you need to add new guard to existing guard in &lt;code&gt;config/auth.php&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   'guards' =&amp;gt; [
        ...
        'staff' =&amp;gt; [
            'driver' =&amp;gt; 'session',
            'provider' =&amp;gt; 'staffs',
        ],
    ],
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this configuration, I add new guard name &lt;strong&gt;staff&lt;/strong&gt;, this guard use driver is session and provider name staffs. Currently, we do not have any provider name staffs, so let's define it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    'providers' =&amp;gt; [
        ...
        'staffs' =&amp;gt; [
            'driver' =&amp;gt; 'eloquent',
            'model' =&amp;gt; App\Models\Staff::class,
        ],
    ],
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this definition, we define provider name staffs using driver eloquent and model we want to use is &lt;code&gt;App\Models\Staff&lt;/code&gt;. Last but not least, we need to configure password part so we can reset password with Staff model.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    'passwords' =&amp;gt; [
        ...
        'staffs' =&amp;gt; [
            'provider' =&amp;gt; 'staffs',
            'table' =&amp;gt; 'staff_password_resets',
            'expire' =&amp;gt; 60,
            'throttle' =&amp;gt; 60,
        ],
    ],
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is quite simple. We use provider name staffs, table is staff_password_resets, expire and throttle is 60 minutes. Since we use staff_password_resets to reset password then remember to migrate it. &lt;/p&gt;

&lt;h2&gt;
  
  
  Ensure
&lt;/h2&gt;

&lt;p&gt;After configuration, we need to ensure these things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Migrate table for reset password
It will look like this one:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public function up()
    {
        Schema::create('staff_password_resets', function (Blueprint $table) {
            $table-&amp;gt;string('email')-&amp;gt;index();
            $table-&amp;gt;string('token');
            $table-&amp;gt;timestamp('created_at')-&amp;gt;nullable();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('staff_password_resets');
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Have Staff model
&lt;/li&gt;
&lt;/ul&gt;

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

namespace App\Models;

// use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;

class Staff extends Authenticatable
{
    use HasApiTo   'guards' =&amp;gt; [
        ...
        'staff' =&amp;gt; [
            'driver' =&amp;gt; 'session',
            'provider' =&amp;gt; 'staffs',
        ],
    ],kens, HasFactory, Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array&amp;lt;int, string&amp;gt;
     */
    protected $fillable = [
        'name',
        'email',
        'password',
    ];

    /**
     * The attributes that should be hidden for serialization.
     *
     * @var array&amp;lt;int, string&amp;gt;
     */
    protected $hidden = [
        'password',
        'remember_token',
    ];

    /**
     * The attributes that should be cast.
     *
     * @var array&amp;lt;string, string&amp;gt;
     */
    protected $casts = [
        'email_verified_at' =&amp;gt; 'datetime',
    ];
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Have data in table&lt;/li&gt;
&lt;/ul&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%2F1zjpgyqtmm1j017f0uda.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%2F1zjpgyqtmm1j017f0uda.png" alt="Data in Staff table" width="800" height="339"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Use new guard
&lt;/h2&gt;

&lt;p&gt;Let's try out new guard. In login logic, you will have code like this:&lt;br&gt;
&lt;code&gt;&lt;br&gt;
Auth::attempt($this-&amp;gt;only('email', 'password'), $this-&amp;gt;boolean('remember'))&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
This one will not work because it will use default guard which is user guard. If we want to use new guard, we need to explicitly use it. Change it to this:&lt;br&gt;
&lt;code&gt;&lt;br&gt;
Auth::guard('staff)-&amp;gt;attempt($this-&amp;gt;only('email', 'password'), $this-&amp;gt;boolean('remember'))&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
So this one tell Laravel to use guard name staff instead of default. Try to login and check the session, you will see that we login successfully and have a session. However, we cannot go to page which ask for authentication. Why? Cause in these pages, we still not use new guard yet. This is my route:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Route::get('/dashboard', function () {
    return view('dashboard');
})-&amp;gt;middleware(['auth', 'verified'])-&amp;gt;name('dashboard');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Take a look at &lt;code&gt;middleware(['auth', 'verified'])&lt;/code&gt;. It will go to auth and verified middlewar before run callback in Route::get. Verified middleware simply check verified_at colume in table is null or not and auth middleware check that user is authenticated or not. Cause we just use auth middleware then again, it use default guard which is user guard. We need to tell it to use staff guard by passing parameter to middleware. Change it to this one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Route::get('/dashboard', function () {
    return view('dashboard');
})-&amp;gt;middleware(['auth:staff', 'verified'])-&amp;gt;name('dashboard');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, we change to use auth middleware with staff guard instead of user guard. Then try to login again and you can access &lt;code&gt;/dashboard&lt;/code&gt; route:&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%2Fpxmii0wuj8moegbrpglv.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%2Fpxmii0wuj8moegbrpglv.png" alt="Dashboard after login" width="800" height="175"&gt;&lt;/a&gt;&lt;br&gt;
Perfection. You rock.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing
&lt;/h2&gt;

&lt;p&gt;Lastly, we need to test to make sure that user in User table cannot use their data to login to &lt;code&gt;/dashboard&lt;/code&gt;. This is user in User table:&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%2Fkpb117vgndts953k93ln.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%2Fkpb117vgndts953k93ln.png" alt="User in User table" width="800" height="152"&gt;&lt;/a&gt;&lt;br&gt;
Try to login using this credential:&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%2Fn6gioim0buecb9gl3exe.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%2Fn6gioim0buecb9gl3exe.png" alt="Try to login with User table" width="800" height="625"&gt;&lt;/a&gt;&lt;br&gt;
Failed. Great, this is what we expect, it cannot find any records cause when using staff guard, it just only take a look in Staff table. That's why, it did not found any records. That's all. Thanks for reading.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>webcomponents</category>
      <category>frontend</category>
      <category>design</category>
    </item>
    <item>
      <title>VIM: Introduction</title>
      <dc:creator>Lâm Kim Phú</dc:creator>
      <pubDate>Sat, 16 Jul 2022 16:02:36 +0000</pubDate>
      <link>https://dev.to/lkp/vim-introduction-2dgl</link>
      <guid>https://dev.to/lkp/vim-introduction-2dgl</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SLPYBso8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5iu1ag4xxvhd9vi8uou9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SLPYBso8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5iu1ag4xxvhd9vi8uou9.png" alt="Image description" width="880" height="495"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Video for this tutorial here:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://youtu.be/BNx7tgDdTi0"&gt;https://youtu.be/BNx7tgDdTi0&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is VIM?
&lt;/h2&gt;

&lt;p&gt;First of all, let’s talk about vi (pronouce vee-eye). Vi editor is a super popular editor in linux because it help you to increase your productivity by just using your keyboard. For that reason, you don’t need to use mouse when you want to move around in your file, you want to copy paste character or word, etc.&lt;/p&gt;

&lt;p&gt;That’s it for vi and VIM is VI iMproved. So VIM is an improvement version of vi.&lt;/p&gt;

&lt;h2&gt;
  
  
  Open VIM
&lt;/h2&gt;

&lt;p&gt;So how can we enter the VIM world. Firstly, you need to have VIM in your computer. If you do not have VIM, then go to install it first. For Ubuntu, you can run this command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo apt install vim&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In Arch based distro:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo pacman -S vim&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;After you have vim in your computer then open your terminal and type vim . The screen you are seeing is VIM welcome screen. It will explain to you what is VIM, version of VIM, VIM’s author, license and some helpful command, especially quit command. Why we need to pay attention to quit command? Because some people use VIM for many years just because they have no idea how to quit VIM. Don’t be that guy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quit VIM
&lt;/h2&gt;

&lt;p&gt;As I say, quit VIM is a very important thing. Thus, to quit VIM, type ESC , after that type :q! . It means quit VIM without saving anything. Another way, you can type ZZ and you can quit VIM, too.&lt;/p&gt;

&lt;h2&gt;
  
  
  Write something, save and quit
&lt;/h2&gt;

&lt;p&gt;Now, open VIM again by typing vim . Type i , you will see INSERT message on the bottom left of your screen. In this mode, you can type anything you want. So let’s type some code: &amp;lt;?php echo 'Hello World'; . Save it by type ESC and type :w filename , it means save this file whose name is filename . In this case, I want it to be index.php then I will type :w index.php and type :q to exit. Next, check files, you will see your new file name index.php . Let’s run it if you have PHP in your computer, if not then skip it php index.php . Hooray, you can open VIM, type something and save it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Small tip and trick
&lt;/h2&gt;

&lt;p&gt;I have a quicker way to name your file. When you open vim, you can type your filename after vim command. For example, vim filename , it means you start to write on file whose name is filename. Then when you want to save it, you just need to run command :w . In addition, if you want to save and quit, you can type :wq , it means write this file and quit.&lt;/p&gt;

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

&lt;p&gt;In this article, we learnt how to open, write, save and quit VIM. See you next time. Until that, I hope you happy with VIM. See ya!&lt;/p&gt;

</description>
      <category>vim</category>
      <category>programming</category>
      <category>editor</category>
    </item>
  </channel>
</rss>
