<?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>Forem: Joseph01</title>
    <description>The latest articles on Forem by Joseph01 (@joseph42a).</description>
    <link>https://forem.com/joseph42a</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%2F791041%2Fef150f2a-449a-4960-98b4-9d947dd1bf69.png</url>
      <title>Forem: Joseph01</title>
      <link>https://forem.com/joseph42a</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/joseph42a"/>
    <language>en</language>
    <item>
      <title>Mastering VPS For Frontend Engineer - Part 3</title>
      <dc:creator>Joseph01</dc:creator>
      <pubDate>Thu, 11 Sep 2025 20:21:07 +0000</pubDate>
      <link>https://forem.com/joseph42a/mastering-vps-for-frontend-engineer-part-3-p83</link>
      <guid>https://forem.com/joseph42a/mastering-vps-for-frontend-engineer-part-3-p83</guid>
      <description>&lt;p&gt;Here we're the final round, after we've put our web applications on VPS, now it's time to improve the Developer Experience by adding Docker and CI/CD github actions, so we will get rid from VPS and automate the process 😃.&lt;/p&gt;

&lt;p&gt;Checkout previous parts if you're new 👉 &lt;a href="https://dev.to/joseph42a/vps-for-frontend-engineer-part-2-7h5"&gt;Part 2&lt;/a&gt; &lt;a href="https://dev.to/joseph42a/vps-for-frontend-engineer-part-1-2lja"&gt;Part 1&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So here is what we'll learn this time&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Adding Firewall
&lt;/h4&gt;

&lt;h4&gt;
  
  
  2. Adding Docker and Docker Compose
&lt;/h4&gt;

&lt;h4&gt;
  
  
  3. Automate Deployment with Github CI/CD action
&lt;/h4&gt;

&lt;h4&gt;
  
  
  4. Adding Load Balancer
&lt;/h4&gt;




&lt;h2&gt;
  
  
  Adding Firewall
&lt;/h2&gt;

&lt;p&gt;Adding firewall is super easy but if you forget this stuff you really face critial security issues and opening doors for attackers, using UFW let us close all the unnecessary ports that are already open by some reasons.&lt;/p&gt;

&lt;p&gt;We'll make sure to only open certain Ports are open, including SSH Port, HTTP and HTTPS connections.&lt;/p&gt;

&lt;p&gt;Let's install &lt;code&gt;ufw&lt;/code&gt; (Uncomplicated Firewall) a package for enabling and disabling access to ports.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt update
sudo apt install ufw
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's enable it and open the ports that we need.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo ufw enable
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then enable what we need (SSH, HTTP, HTTPS)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now lets check all the ports by&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo ufw status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;See all the opened port, and if you've backend you can open a port for that as well&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo ufw allow 3002/tcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This we will open 3002/tcp port for backend requests.&lt;/p&gt;

&lt;h2&gt;
  
  
  Docker &amp;amp; Docker Compose
&lt;/h2&gt;

&lt;p&gt;With Docker, your app will run the same way everywhere, on your computer, your teammate’s computer, or even on a cloud server.&lt;/p&gt;

&lt;p&gt;The core principle of Docker is straightforward: we create a Dockerfile that contains all the information needed to run our project. For example, if we have a Next.js app, we specify Node.js as the environment and use npm (or yarn) to run it. In the Dockerfile, we write these instructions step by step.&lt;/p&gt;

&lt;p&gt;When we build the Dockerfile, Docker creates something called an image, a snapshot that includes our app, its dependencies, and the environment it needs.&lt;/p&gt;

&lt;p&gt;From this image, we can launch a container. A container is a running instance of our app, isolated from everything else, and usually exposed through specific ports (for example, port 3000 for a Next.js app).&lt;/p&gt;

&lt;p&gt;Now let's instead using PM2 we will use Docker to build and run our NextJS app.&lt;/p&gt;

&lt;p&gt;One more thing before we start with Docker: we’ll be using Docker Compose. Docker Compose is super helpful when you have multiple services or more than one container. Instead of writing multiple docker run commands, you can simply define your services in a docker-compose.yml file and let Compose handle running, managing, and connecting the containers for you.&lt;/p&gt;

&lt;h3&gt;
  
  
  Installing Docker and Docker Compose
&lt;/h3&gt;

&lt;p&gt;We should setup repository, bellow we can get it for Ubuntu,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

# Add the repository to Apt sources:
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release &amp;amp;&amp;amp; echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list &amp;gt; /dev/null
sudo apt-get update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then add the plugin&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt-get update
sudo apt-get install docker-compose-plugin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And verify the installation&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker compose version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Writing Dockerfile
&lt;/h3&gt;

&lt;p&gt;We've to got the our project directory which was under &lt;code&gt;/var/www/frontend/&lt;/code&gt; and create our docker file instruction.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd /var/www/frontend/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;create Dockerfile&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;and fill it with the content, in our case we use nodejs 22 image, and some instruction to build and run our production app.&lt;/p&gt;

&lt;p&gt;You can copy paste this or maybe you want to use another version of NodeJS based on your needs&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM node:22

WORKDIR /app

COPY package*.json ./
RUN npm install

COPY . .

RUN npm run build

EXPOSE 3000

CMD ["npm", "start"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let’s break it down:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The second line, WORKDIR &lt;code&gt;/app&lt;/code&gt;, sets the working directory inside the Docker container. All subsequent commands run from /app.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;COPY package*.json ./&lt;/code&gt; copies the &lt;code&gt;package.json&lt;/code&gt; and &lt;code&gt;package-lock.json&lt;/code&gt; files into the container.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;RUN npm install&lt;/code&gt; installs all the dependencies listed in those files.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;COPY . .&lt;/code&gt; copies the rest of your source code into &lt;code&gt;/app&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;RUN npm run build&lt;/code&gt; builds the Next.js app.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;EXPOSE 3000&lt;/code&gt; opens port 3000 inside the container, because Next.js runs on port 3000 by default when started with npm start.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;CMD ["npm", "start"]&lt;/code&gt; tells Docker how to start the app when the container runs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As you can see, it’s a straightforward set of instructions. Once this Dockerfile is used to build an image, the image becomes a &lt;br&gt;
&lt;strong&gt;ready-to-use&lt;/strong&gt; environment that can spawn containers anytime, each running your Next.js app in an isolated environment.&lt;/p&gt;

&lt;p&gt;Lastly exit and save the file, click &lt;code&gt;Esc&lt;/code&gt; and type &lt;code&gt;:wq&lt;/code&gt; to save and quite the Dockerfile.&lt;/p&gt;
&lt;h3&gt;
  
  
  Build Docker Image
&lt;/h3&gt;

&lt;p&gt;Now with our &lt;code&gt;Dockerfile&lt;/code&gt; in place we will create an &lt;code&gt;Image&lt;/code&gt; from those instructions we put in &lt;code&gt;Dockerfile&lt;/code&gt;, before using &lt;strong&gt;Docker Compose&lt;/strong&gt; we will use pure Docker commands, so you see what headache will Docker Compose move away.&lt;/p&gt;

&lt;p&gt;Build image by running this command in same directory of our Dockerfile&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo docker build -t myfrontend:latest .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;-t myfrontend&lt;/code&gt; → gives the image a name (myfrontend) and tag (latest).&lt;/p&gt;

&lt;p&gt;&lt;code&gt;.&lt;/code&gt; → means current directory.&lt;/p&gt;

&lt;p&gt;Now after it builds successfully, let's run reall container, but first make sure you stop it from pm2 if you running with pm2 with&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pm2 stop frontend
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run docker container (container is basically an instance running from the &lt;code&gt;image&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;sudo docker run -d -p 3000:3000 --name myfrontend_container myfrontend:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this the docker is running in the background (by using &lt;code&gt;-d&lt;/code&gt; mode) and we mapped into port &lt;code&gt;3000&lt;/code&gt; from our host to &lt;code&gt;3000&lt;/code&gt; port on container, and we give it a name (with &lt;code&gt;--name&lt;/code&gt;) &lt;strong&gt;myfrontend_container&lt;/strong&gt; lastly we should specify the image name as well (the one we just created above) &lt;strong&gt;myfrontend:latest&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Now again your app is live on &lt;code&gt;http://localhost:3000&lt;/code&gt;, which is we already mapped this to our main domain from nginx config of our NextJS app in &lt;strong&gt;Part 1&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Check Containers
&lt;/h3&gt;

&lt;p&gt;You can see and check your running container with&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo docker ps
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will show all your running containers, in our case we've only one case, if you've more you can add &lt;code&gt;-a&lt;/code&gt; at end to list all running and stopped containers.&lt;/p&gt;

&lt;p&gt;Now to stop it easily run&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo docker stop myfrontend_container
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will stop our frontend app, to start it again run&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo docker start myfrontend_container
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;now if you want to remove it, lets say you've lots of containers you want to remove some of unused ones, to free up some memory spaces, you can run&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo docker rm oldfrontend_container
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or if you want to even remove an image you can run this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo docker rmi oldfrontend:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;but bare in mind, you should first stop and remove all the containers that uses that image, cause all of them depending on it.&lt;/p&gt;

&lt;p&gt;You can list the images you've with&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo docker images
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also check the logs of your app, in case of having some issues or bugs,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo docker logs myfrontend_container
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;just give a name of your containers and see the logs, that is it, powerfull yeah! I know, lets make it more powerfull by simplifying it with &lt;strong&gt;Docker Compose&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using Docker Compose
&lt;/h3&gt;

&lt;p&gt;Instead of starting containers manually with long docker run commands, you write all your app’s services (backend, frontend, database, etc.) in one YAML file (docker-compose.yml) and run them with a single command.&lt;/p&gt;

&lt;p&gt;Lets write for our NextJS project and create docker file.&lt;/p&gt;

&lt;p&gt;Create docker compose yaml file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vi docker-compose.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and put fill it with these content&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;services:
  frontend:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: frontend_app
    ports:
      - "3000:3000"
    restart: always
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In Docker Compose, everything runs inside a &lt;code&gt;service&lt;/code&gt; (like “mini apps”), we've only one service called &lt;code&gt;frontend&lt;/code&gt;, and we tell some information about building, like it's context, that tells Docker to build from the current folder &lt;code&gt;(.)&lt;/code&gt;, and we explicitly tell which one is the dockerfile (it also default to use &lt;code&gt;Dockerfile&lt;/code&gt;) incase you're using different file name, and we give it a name &lt;code&gt;frontend_app&lt;/code&gt;, as well as mapping host port &lt;code&gt;3000&lt;/code&gt; → container port &lt;code&gt;3000&lt;/code&gt;, and to make Docker to restart incase of the container stops or your machine reboots.&lt;/p&gt;

&lt;p&gt;Now here is fun part, let's easily run and make the docker up and running&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo docker compose up -d
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;-d&lt;/code&gt; means running the process in the background, and with this simple command we started the services.&lt;/p&gt;

&lt;p&gt;To stop the service&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo docker compose down
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;if you check running docker you'll see that &lt;code&gt;frontend_app&lt;/code&gt; is in the running list&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo docker ps
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  CI/CD Github actions
&lt;/h3&gt;

&lt;p&gt;We currently have our app running on port 3000, but here’s the problem: every time you make a change or push an update, you’d have to manually access the server, rebuild Docker, and restart the container. That’s not only repetitive but also a poor Developer Experience (DX).&lt;/p&gt;

&lt;p&gt;Wouldn’t it be great if your app could automatically update in production the moment you push code just like Vercel handles automatic deployments?&lt;/p&gt;

&lt;p&gt;That’s where CI/CD (Continuous Integration / Continuous Delivery) with GitHub Actions comes in. As the name suggests, it continuously integrates your changes and delivers them to production. Every time you push code, GitHub Actions can automatically run tests, linting, builds, and even deploy updates to your server.&lt;/p&gt;

&lt;p&gt;With CI/CD, you no longer need to log into your server, pull changes, and restart Docker manually, your workflow is automated, your app stays up to date, and you get a much smoother development and deployment process.&lt;/p&gt;

&lt;p&gt;All of this is defined in YAML workflow files stored in &lt;code&gt;.github/workflows/&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now before writing the &lt;code&gt;yaml&lt;/code&gt; file for auto deployment with github action we need a couple of thing.&lt;/p&gt;

&lt;p&gt;Establishing SSH connection with github, so github can access to our VPS server and do its job, and apparently we will save sensitive information in our GitHub repository variables.&lt;/p&gt;

&lt;p&gt;Sine we already did SSH connection process in first part, you can get instructions from there, in summary you need to do&lt;br&gt;
1- Generate an SSH Key Pair&lt;br&gt;
2- Add Public Key to VPS (to &lt;code&gt;authorized_keys&lt;/code&gt;)&lt;br&gt;
3- Add Secrets to GitHub (Now on Github same repository open Settings → Secrets and variables → Actions, add &lt;code&gt;VPS_SSH_KEY&lt;/code&gt;, open the file id_ed25519 (private key) and paste the whole content (including -----BEGIN OPEN SSH PRIVATE KEY-----).&lt;/p&gt;

&lt;p&gt;Beside this also we need to add two more sensitive information which your vps user and server IP address, add &lt;code&gt;VPS_HOST&lt;/code&gt; (your IP), &lt;code&gt;VPS_USER&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now that we're ready lets create a deploy.yml file under &lt;code&gt;.github/workflows/deploy.yml&lt;/code&gt; and paste that code in&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;name: Deploy to VPS

on:
  push:
    branches: [main] # runs on push/merge to main

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout repository (for context/logs)
        uses: actions/checkout@v4

      - name: Deploy via SSH
        uses: appleboy/ssh-action@v1.0.0
        with:
          host: ${{ secrets.VPS_HOST }}
          username: ${{ secrets.VPS_USER }}
          key: ${{ secrets.VPS_SSH_KEY }}
          script_stop: true
          script: |
            set -e
            cd /var/www/portfolio

            echo "🔄 Pulling latest code..."
            git fetch origin main
            git reset --hard origin/main

            echo "🛑 Stopping and removing old containers..."
            docker compose down --remove-orphans

            echo "🧹 Cleaning up unused images, volumes, and cache..."
            docker system prune -af --volumes

            echo "📦 Rebuilding Docker images from scratch..."
            docker compose build --no-cache

            echo "🚀 Starting containers..."
            docker compose up -d

            echo "✅ Deployment finished!"
            docker compose ps
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ok, so this makes an automation that deploys your app to a VPS every time you push code to the main branch. Instead of manually logging into your server and rebuilding your app, GitHub does it for you. The workflow runs on a temporary Ubuntu machine, connects to your VPS securely over SSH (using the secrets you’ve added to GitHub), and then executes a series of commands on the server.&lt;/p&gt;

&lt;p&gt;Once connected, it pulls the latest code from GitHub, stops and removes old Docker containers, cleans up unused images and volumes, rebuilds fresh Docker images, and finally starts the app again. In short, this setup makes sure your app is always up to date in production automatically, just by pushing code to GitHub.&lt;/p&gt;

&lt;h2&gt;
  
  
  Load Balancer
&lt;/h2&gt;

&lt;p&gt;With Docker, we can easily run multiple instances of our application. For example, if your web app gets a lot of traffic and starts slowing down, we can create additional instances and distribute users across them. This way, no single instance gets overloaded, and your app stays fast and responsive.&lt;/p&gt;

&lt;p&gt;The good news is that NGINX can handle this routing for us. All we need to do is spin up another Docker instance of our app and configure NGINX to send traffic to the new instance. This makes scaling your app simple and efficient.&lt;/p&gt;

&lt;p&gt;So first update our docker compose to create two instance of our app instead of one&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vi docker-compose.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then simply add another app instance like on port 3001&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;services:
  frontend:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: frontend_app
    ports:
      - "3000:3000"
    restart: always

  frontend2:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "3001:3000"
    restart: always
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And with this it will always create two instance of your app for port 3000 and 3001, and we can tell nginx by going to &lt;code&gt;/etc/nginx/nginx.conf/&lt;/code&gt; and create an upstream object locating both our apps.&lt;br&gt;
&lt;/p&gt;

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

                server localhost:3000;
                server localhost:3001;
        }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lastly we only left to update the site config to point to our upstream we just create &lt;code&gt;nextjsfrontend&lt;/code&gt;, move to your app server config under &lt;code&gt;/etc/nginx/sites-available/frontend/&lt;/code&gt; and make sure to update the location block to point to our &lt;code&gt;nextjsfrontend&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;location / {
   proxy_pass http://nextjsfrontend;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;now just restart your nginx and here you go, you've got load balancer setup already.&lt;/p&gt;

&lt;p&gt;I hope you enjoyed this tutorials I know it was long, and stay calm and enjoy learning, let me know if you've got any question.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>devops</category>
      <category>vps</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Mastering VPS For Frontend Engineer - Part 2</title>
      <dc:creator>Joseph01</dc:creator>
      <pubDate>Fri, 05 Sep 2025 14:33:05 +0000</pubDate>
      <link>https://forem.com/joseph42a/vps-for-frontend-engineer-part-2-7h5</link>
      <guid>https://forem.com/joseph42a/vps-for-frontend-engineer-part-2-7h5</guid>
      <description>&lt;p&gt;In &lt;a href="https://dev.to/joseph42a/vps-for-frontend-engineer-part-1-2lja"&gt;previous article&lt;/a&gt; we bought VPS, configured SSH and disabled the root access, which means our custom VPS authentication is ready to be used by us.&lt;/p&gt;

&lt;p&gt;Now let's dive into adding more stuff to it&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Installing and configuring NGINX
&lt;/h4&gt;

&lt;h4&gt;
  
  
  2. Setting up Node.js via NVM
&lt;/h4&gt;

&lt;h4&gt;
  
  
  3. Deploying a Next.js frontend with NGINX and PM2
&lt;/h4&gt;

&lt;h4&gt;
  
  
  4. Serving static React apps directly with NGINX
&lt;/h4&gt;

&lt;h4&gt;
  
  
  5. Linking a custom domain and configuring DNS records
&lt;/h4&gt;

&lt;h4&gt;
  
  
  6. Adding a subdomain for backend services
&lt;/h4&gt;

&lt;h4&gt;
  
  
  7. Securing the server with a free SSL certificate from Let’s Encrypt
&lt;/h4&gt;

&lt;h2&gt;
  
  
  Why NGINX ?!
&lt;/h2&gt;

&lt;p&gt;Now our VPS without NGINX can not serve our frontend and backend application, NGINX is responsible to handle large number of connection and its super fast and efficient.&lt;/p&gt;

&lt;p&gt;One thing I like the most is &lt;strong&gt;Reverse Proxy&lt;/strong&gt; before requests go to your backend application directly, it will go to NGINX first and direct them to correct service, you can simply say if users hits &lt;code&gt;/api&lt;/code&gt; direct them to my python application.&lt;/p&gt;

&lt;p&gt;Another thing is &lt;strong&gt;Load Balancing&lt;/strong&gt;, imagine you've a lot of users and sometime lots of users uses your service at the same time, this add a lot more loads to your service and in result makes your app slow, what you can do you can have more than one running instance of your server, and NGINX will handle the traffic distribution and this will makes your service to be much faster.&lt;/p&gt;

&lt;p&gt;There is much more about NGINX like &lt;strong&gt;SSL/TLS&lt;/strong&gt;, &lt;strong&gt;Security&lt;/strong&gt; and &lt;strong&gt;Concurrency&lt;/strong&gt;, let's go and configure it.&lt;/p&gt;

&lt;p&gt;Let's get started, install by running this on your server&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt update
sudo apt install nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's quickly get familiar with some of the most used files on NGINX, that you mostly interact with them.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;/etc/nginx/nginx.conf&lt;/strong&gt; This is main global configuration, usually we create separate site configurations in other folder &lt;strong&gt;/sites-enabled&lt;/strong&gt; then we'll just import it here so to be executable by nginx.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;/etc/nginx/sites-enabled/&lt;/strong&gt; this is where we put our nginx server block config files here, maybe you've &lt;strong&gt;portfolio&lt;/strong&gt; or &lt;strong&gt;blog.portfolio&lt;/strong&gt;, or using this file linked (symbolic linking) with &lt;strong&gt;sites-available&lt;/strong&gt; specific files.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;/etc/nginx/sites-available&lt;/strong&gt; As of best practices it is recommended to put our NGINX config files here and linking it with &lt;strong&gt;/sites-enabled&lt;/strong&gt; directory, (cause nginx will only process files that is under &lt;strong&gt;/sites-enabled&lt;/strong&gt;), technically we can skip the &lt;strong&gt;/sites-available&lt;/strong&gt; directory if we want to but in that case we manually has to import and include the files from the &lt;strong&gt;nginx.conf&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;/var/www&lt;/strong&gt; this is conventional location for web server content, means your source file it is not mandatory to put your projects directory here but its recomended to put your projects there, it is just standardized and secure location.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Deploying Frontend
&lt;/h2&gt;

&lt;p&gt;Clone or upload your project source code under &lt;code&gt;/var/www/frontend&lt;/code&gt;, here lets assume we've got NextJS Project.&lt;/p&gt;

&lt;p&gt;and inside that build your app here for production by&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm run build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;this will create &lt;strong&gt;.next&lt;/strong&gt; directory contains statics and server(for server side codes) this is crucial step and prepare our app to run efficiently.&lt;/p&gt;

&lt;p&gt;Second create nginx config file under &lt;code&gt;/etc/nginx/sites-available/frontend&lt;/code&gt; and add the config,&lt;br&gt;
1- &lt;code&gt;cd /etc/nginx/sites-available/&lt;/code&gt;&lt;br&gt;
2- &lt;code&gt;vi frontend&lt;/code&gt;&lt;br&gt;
3-&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;server {
    listen 80;
    listen [::]:80;

    server_name (your_server_ip); # temp for now (we'll use real domain)

    location / {
        proxy_pass http://localhost:3000;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;let's explain line by line&lt;br&gt;
the &lt;code&gt;server&lt;/code&gt; block is our virtual host, it contains a set of rules for single website or app, we can have more for other web apps.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;listen 80&lt;/code&gt; this tells nginx to listen for incoming connection on port 80 which is for HTTP traffic, when users types your server IP address they connect via this port. &lt;code&gt;listen [::]:80&lt;/code&gt; this is the same as &lt;code&gt;80&lt;/code&gt; only it is for IPv6 the first one was for IPv4 addresses.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;server_name&lt;/code&gt; this define the IP address or the domain name that this block is responding to, right now it is our server's public IP address, later we'll change to be real domain (e.g., example.com)&lt;/p&gt;

&lt;p&gt;&lt;code&gt;location /&lt;/code&gt; this define how to handle request when users hit the root address, like &lt;code&gt;https://example.com/&lt;/code&gt; this is root address.&lt;/p&gt;

&lt;p&gt;lastly &lt;code&gt;proxy_pass http://localhost:3000;&lt;/code&gt; will tell NGINX to forward the request from root to our internal port on &lt;code&gt;3000&lt;/code&gt; which apparently our frontend app will be running on.&lt;/p&gt;

&lt;p&gt;4- Now save and exit the file hit &lt;code&gt;Esc&lt;/code&gt; from your keyboard and type &lt;code&gt;wq&lt;/code&gt; then &lt;code&gt;Enter&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;5- We should create a symbolic link so we'll create a symbolic file under &lt;code&gt;/sites-enabled&lt;/code&gt; to let NGINX process our configuration, by running this command, make sure you're at &lt;code&gt;/etc/nginx/&lt;/code&gt; directory and run this command bellow&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo ln -s /etc/nginx/sites-available/frontend /etc/nginx/sites-enabled/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we'll test before restarting the NGINX server by&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo nginx -t
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you followed the steps you should be good to go.&lt;/p&gt;

&lt;p&gt;Ok, the last step before restarting the NGINX and enable our web app, is to actually run our frontend app on port 3000, we built for production already now lets run it using &lt;code&gt;pm2&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why PM2
&lt;/h2&gt;

&lt;p&gt;pm2 is a production process manager for Node.js apps, and since our app is NextJS and it may have SSR feature which is needs a node environment to run, otherwise if you only using pure ReactJS or VueJS they're purely static files no need for server side rendering so you'll just define the root in your server config.&lt;/p&gt;

&lt;p&gt;So, if you using purely react just add or modify the location block of your NGINX config&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    root /var/www/frontend/build;
    index index.html;

    location / {
        try_files $uri /index.html;
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This way you don't need to use &lt;code&gt;pm2&lt;/code&gt; because your app is simply a static, one crucial thing here is the &lt;code&gt;location&lt;/code&gt; block that tell NGINX to let the React's routing mechanism to handle the routing, cause if you did miss this part a user will hit &lt;code&gt;/about&lt;/code&gt; NGINX will look for it under your &lt;code&gt;/frontend/build/about/&lt;/code&gt; and it is not there but if you add the location block it will let reactJS's Javascript-driven routing handles it, now simply restart NGINX with &lt;code&gt;sudo systemctl restart nginx&lt;/code&gt; you should see your static files. Tadaa!!&lt;/p&gt;

&lt;p&gt;But if you're using NextJS lets install pm2 and run the app with it.&lt;/p&gt;

&lt;p&gt;Install pm2&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo npm install -g pm2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;PM2 will let us manage multiple apps, like running, restarting, stopping and generate logs and monitor performance, it is super nice.&lt;/p&gt;

&lt;p&gt;Now let's go to the frontend directory where we've our built file and we've got package.json file where there is a script for running that build production file for us.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;package.json&lt;/code&gt; make sure you've this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  "scripts": {
    "build": "next build",
    "start": "next start",
  },
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now run the PM2 with this and name your running process on pm2&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pm2 start npm --name "frontend-app" -- run start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;now restart nginx and go to your server's IP address, and you'll see your web app live on VPS, Tada!!!&lt;/p&gt;

&lt;h2&gt;
  
  
  Add Domain
&lt;/h2&gt;

&lt;p&gt;Of course you'll not share the server's public IP Address! lets add the domain I'll go with &lt;a href="https://www.namecheap.com/" rel="noopener noreferrer"&gt;namecheap&lt;/a&gt;, go ahead and pick a cheap domain in their homepage.&lt;/p&gt;

&lt;p&gt;Once you purchased a domain, one easy step left, and it is basically you’ll point your domain’s DNS records (managed at Namecheap) to DigitalOcean’s nameservers.&lt;/p&gt;

&lt;p&gt;Let's update the DNS record from the namecheap step by step&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to Domain List → Manage next to your domain.&lt;/li&gt;
&lt;li&gt;Under Nameservers, choose Custom DNS.&lt;/li&gt;
&lt;li&gt;Enter these DigitalOcean nameservers:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ns1.digitalocean.com
ns2.digitalocean.com
ns3.digitalocean.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Save changes (may take up to 24–48 hours globally, but often faster).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now going back to digitalocean dashboard click on &lt;br&gt;
Networking → Domains.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add your domain name (e.g., example.com).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Lastly we need to add two records, &lt;code&gt;@&lt;/code&gt; record for root and &lt;code&gt;CNAME&lt;/code&gt; record for &lt;code&gt;www&lt;/code&gt; so our domain will be available by &lt;code&gt;www.example.com&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Click your domain you just added it&lt;/li&gt;
&lt;li&gt;You can see a button &lt;strong&gt;Create Record&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Choose &lt;code&gt;A&lt;/code&gt; Record with its value &lt;code&gt;@&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;Choose &lt;code&gt;CNAME&lt;/code&gt; Record with value of &lt;code&gt;www&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now after saving these settings we should wait for propagation process to take in place it may take a few minute or a few hours, just wait patiently if exceeded 48hrs contact the support team to get help.&lt;/p&gt;

&lt;p&gt;Finally go ahead and replace the IP Address of our server from the NGINX config to be pointing to our new domain.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;etc/nginx/sites-available/frontend&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;server {
    listen 80;
    server_name example.com www.example.com;   # or your_server_IP
    ...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then restart the NGINX&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo systemctl restart nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note/ there is one thing, I face it to when I was experimenting with, for my domain I've choose &lt;code&gt;.dev&lt;/code&gt; which is managed and owned by google and it requires me to have and active SSL Certificate and from this point I didn't had it so I couldn't access my website, but no worries once we add the certificate our web app will be active and online, just bare in mind that if your domain was not reachable at this point check your domain extension if accessible without SSL or you can check if the propagation has ended by visiting this website &lt;a href="https://dnschecker.org/" rel="noopener noreferrer"&gt;DNS Checker&lt;/a&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Adding SSL Certificate
&lt;/h2&gt;

&lt;p&gt;So, here we are this is by far one of the most amazing steps, in this step your step you officially marked as a secure site (HTTPS) and google will rank it better (SEO rank HTTPS over HTTP), and all this comes from &lt;a href="https://letsencrypt.org/" rel="noopener noreferrer"&gt;Let's Encrypt&lt;/a&gt; organization and its all free, we can simply by simple commands enable it and make an auto renew when expired, sometime companies or providers will sell these if you're using shared hosting.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Download certbot on Ubuntu/Dabian
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt install certbot python3-certbot-nginx -y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And apply for your domain for both &lt;code&gt;A Record&lt;/code&gt; and &lt;code&gt;CNAME&lt;/code&gt; Record we just added previously.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lastly we'll enable auto renew, cause &lt;strong&gt;lets encrypt&lt;/strong&gt;'s certificates will expire in 90 days&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo certbot renew --dry-run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you've officially got your website up and running on VPS, whether it is static web application like ReactJS or it has SSR feature like NextJS.&lt;/p&gt;

&lt;p&gt;Note/ if you've got a backend as well do exact same thing we just did it for Nextjs, in summary you'll need these steps&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Clone your backend project under &lt;code&gt;/var/www/backend/&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Build for production and run it with PM2&lt;/li&gt;
&lt;li&gt;Add the NGINX configuration under &lt;code&gt;/etc/nginx/sites-available/backend&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Create symbolic link for &lt;strong&gt;sites-enabled&lt;/strong&gt; so NGINX will process it&lt;/li&gt;
&lt;li&gt;Add &lt;code&gt;A Record&lt;/code&gt; for your sub domain (e.g. api.yourdomain.com)&lt;/li&gt;
&lt;li&gt;Restart and Test NGINX configuration&lt;/li&gt;
&lt;li&gt;Add SSL Certificate with certbot and enable auto renew&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;At this stage, our VPS can serve production apps securely with HTTPS. In Part 3, we’ll improve security, add CI/CD, Load balancer and explore containerization.&lt;/p&gt;

</description>
      <category>vps</category>
      <category>deployment</category>
      <category>webdev</category>
      <category>devops</category>
    </item>
    <item>
      <title>Mastering VPS For Frontend Engineer - Part 1</title>
      <dc:creator>Joseph01</dc:creator>
      <pubDate>Fri, 15 Aug 2025 08:07:48 +0000</pubDate>
      <link>https://forem.com/joseph42a/vps-for-frontend-engineer-part-1-2lja</link>
      <guid>https://forem.com/joseph42a/vps-for-frontend-engineer-part-1-2lja</guid>
      <description>&lt;p&gt;I remember the first time I tried to deploy my web app on a VPS. It was a horrible experience! Then I switched to Cpanel deployment. Ohh, that was even worse than a VPS, lol. After years of taking on multiple full-stack projects, I truly believe if I had taken a course earlier, I would be on another level right now.&lt;/p&gt;

&lt;p&gt;So, if you'd love to dive into DevOps, stick with me and practice alongside. We'll cover more things later, like AWS, Docker, and more.&lt;/p&gt;

&lt;p&gt;I know you may be asking why a frontend developer needs VPS knowledge when you can deploy an application with one click?&lt;/p&gt;

&lt;p&gt;Vercel, Netlify, GitHub, etc...&lt;/p&gt;

&lt;p&gt;You're correct, if you're just a "vibe coder"!&lt;/p&gt;

&lt;p&gt;To be honest, it has a lot of benefits. For starters, it gives you free SSL, which many providers are now selling you!&lt;/p&gt;

&lt;p&gt;Don't stick with only frontend skills in the age of AI. To be honest, as a frontend developer with over 5 years of experience, I don't think we'll survive with only FE skills.&lt;/p&gt;

&lt;p&gt;Learn a new skill, open a new horizon. Instead of complaining, explore the world!&lt;/p&gt;

&lt;p&gt;As someone who has learned these skills, I can now communicate and better understand what my team is really talking about.&lt;/p&gt;

&lt;p&gt;CI/CD, Docker, Redis, Cloudflare, etc...&lt;/p&gt;

&lt;p&gt;Here's the thing: today's market is rough! You have to gain more knowledge and not just focus on one area, especially frontend.&lt;/p&gt;

&lt;p&gt;And don't worry if you enjoy coding already, you'll find VPS super fun to learn. Many new concepts and pains you currently suffer from will go away.&lt;/p&gt;

&lt;p&gt;One last thing: it's super easy to learn but incredibly valuable to have in your skillset.&lt;/p&gt;

&lt;p&gt;Let's dive in!&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;What we'll learn in this article?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;You'll learn and master the following points in three articles.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Part 1&lt;/strong&gt;
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1.  Setting Up Our Custom VPS
&lt;/h4&gt;

&lt;h4&gt;
  
  
  2.  Best Practices for Accessing and Using a VPS
&lt;/h4&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Part 2&lt;/strong&gt;
&lt;/h3&gt;

&lt;h4&gt;
  
  
  3.  Falling in Love with NGINX
&lt;/h4&gt;

&lt;h4&gt;
  
  
  4.  Configure a Domain and Subdomain with Free SSL
&lt;/h4&gt;

&lt;h4&gt;
  
  
  5.  Setting Up Node.js and Next.js applications
&lt;/h4&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Part 3&lt;/strong&gt;
&lt;/h3&gt;

&lt;h4&gt;
  
  
  6.  Docker
&lt;/h4&gt;

&lt;h4&gt;
  
  
  7.  CI/CD and GitHub Actions so you don't need to touch the VPS again, lol!
&lt;/h4&gt;

&lt;h4&gt;
  
  
  8.  Load Balancer
&lt;/h4&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;First Step: Buying a VPS&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;First, we have to buy a VPS. One of the best providers is &lt;strong&gt;DigitalOcean&lt;/strong&gt;. For learning purposes, it won't cost you anything for the first 2 months. You can click the link below to sign up and get a $200 credit to use on DigitalOcean.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.digitalocean.com/?refcode=3bea45abfdb1&amp;amp;utm_campaign=Referral_Invite&amp;amp;utm_medium=Referral_Program&amp;amp;utm_source=CopyPaste" rel="noopener noreferrer"&gt;digitalOcean&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After that, go ahead and create a Droplet (VPS). Choose and fill out the options. The important thing here is that we're using &lt;strong&gt;Ubuntu&lt;/strong&gt;, so make sure you're using the latest LTS version.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Setup SSH to Login&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;One of the best security practices is to log in via SSH instead of a password.&lt;/p&gt;

&lt;p&gt;SSH login is a secure way to connect to a remote server over the internet using the Secure Shell (SSH) protocol.&lt;/p&gt;

&lt;p&gt;So, in a nutshell, with SSH key login, you have:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Public Key&lt;/strong&gt; → Stored on the server (&lt;code&gt;~/.ssh/authorized_keys&lt;/code&gt;) to recognize you.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Private Key&lt;/strong&gt; → Kept on your local machine and never shared; used to prove your identity when connecting.&lt;/p&gt;

&lt;p&gt;From DigitalOcean, click on &lt;strong&gt;Add SSH Key&lt;/strong&gt; as you see below.&lt;/p&gt;

&lt;p&gt;Okay, now let's create an SSH key and upload the public key here on DigitalOcean.&lt;/p&gt;

&lt;p&gt;It's super easy to create SSH keys. Run:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;You can give it a name (I'll use &lt;code&gt;frontend-key&lt;/code&gt;) or let it be the default name and path (&lt;code&gt;~/.ssh/&lt;/code&gt;). It will ask you to create a passphrase (you can skip this if you'd like).&lt;/p&gt;

&lt;p&gt;Now you've got two keys:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Private key: &lt;code&gt;~/.ssh/frontend-key&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt; Public key: &lt;code&gt;~/.ssh/frontend-key.pub&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Note that you can differentiate the public and private keys by their file extension. The public key ends with &lt;code&gt;.pub&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now, in order to log in to the server, we always have to specify where our private key is by running this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssh -i ~/.ssh/frontend-key root@server_ip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To avoid specifying the private key every time, we can run an &lt;code&gt;ssh-agent&lt;/code&gt; and add the private key to it. That way, we can just run &lt;code&gt;ssh root@server_ip&lt;/code&gt; to log in to the server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;eval "$(ssh-agent -s)"
ssh-add ~/.ssh/(your_private_ssh_key)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One last thing before we try to access our server: we have to add our public key to the server (remember, the one that ends with &lt;code&gt;.pub&lt;/code&gt; is the public key).&lt;/p&gt;

&lt;p&gt;Using the &lt;code&gt;cat&lt;/code&gt; command, we can display the content inside the &lt;code&gt;.pub&lt;/code&gt; file and copy it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cat ~/.ssh/(your_private_ssh_key).pub
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Upload this key to the &lt;strong&gt;Add SSH Key&lt;/strong&gt; section in DigitalOcean.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Disable the root User&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The next security best practice is to disable login for the &lt;strong&gt;root&lt;/strong&gt; user. Since the root user is the highest level and can do anything on our system, disabling it protects us from attacks and the risk of unauthorized access.&lt;/p&gt;

&lt;p&gt;The first step is to create a new user. We want to be 100% sure the new user works correctly before we disable the root user.&lt;/p&gt;

&lt;p&gt;Run this command to create a new user:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; You may need to run this command with &lt;code&gt;sudo&lt;/code&gt; if you encounter a permission denied error.&lt;/p&gt;

&lt;p&gt;It will ask you to create and repeat a password. You can skip the other questions by simply pressing Enter on your keyboard.&lt;/p&gt;

&lt;p&gt;Then, we'll change the group for that user to be &lt;code&gt;sudo&lt;/code&gt; so they can run high-level commands, just like the root user.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;usermod -aG sudo newUser
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Switch to the newly created user:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Now, before testing this user, we have to upload the public key into a special file called &lt;code&gt;authorized_keys&lt;/code&gt;. Go ahead and create the SSH directory for your new user:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir ~/.ssh
chmod 700 ~/.ssh
cd ~/.ssh
touch authorized_keys
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can open that file with the &lt;code&gt;vim&lt;/code&gt; or &lt;code&gt;nano&lt;/code&gt; editor and paste the public key. You can use the same public key you used for the root user or create a new one. (Note: You may need to run this with &lt;code&gt;sudo&lt;/code&gt;, e.g., &lt;code&gt;sudo vi authorized_keys&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;The last step is to change the permissions for that file and restart the SSH service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;chmod 644 authorized_keys
systemctl restart ssh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The number &lt;code&gt;644&lt;/code&gt; means that only we (the owner) can read and write, but other users can only read. You may not understand these numbers, but they all have a meaning. They are represented in octal, which is a base-8 number system.&lt;/p&gt;

&lt;p&gt;Each permission is assigned a value:&lt;br&gt;
read (r) = 4&lt;br&gt;
write (w) = 2&lt;br&gt;
execute (x) = 1&lt;/p&gt;

&lt;p&gt;You add these values to get the number for each category. For example, to give full read, write, and execute permissions, you'll use 7 (rwx = 4+2+1 = 7). We used three digits together (&lt;code&gt;644&lt;/code&gt;), which means the first digit is for the owner, the second is for the group, and the third is for others.&lt;/p&gt;

&lt;p&gt;So if you want to give all types of users all permissions, you would say &lt;code&gt;777&lt;/code&gt; (rwx).&lt;/p&gt;

&lt;p&gt;Now, test logging in with this user:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssh newUser@server_ip 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Boom!&lt;/p&gt;

&lt;p&gt;Now let's &lt;strong&gt;disable the root user&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Switch back to the root user:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Then, go to the SSH daemon configuration file at &lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt; to disable root login. Find the line that says &lt;code&gt;PermitRootLogin&lt;/code&gt; and change it to &lt;code&gt;no&lt;/code&gt;. (But please make sure you've already tested your new sudo user, otherwise you'll lose everything!).&lt;/p&gt;

&lt;p&gt;Now our server is ready, and we can securely access it via SSH without the root user.&lt;/p&gt;

&lt;p&gt;In &lt;strong&gt;Part 2&lt;/strong&gt;, we will set up NGINX and prepare our server for a full-stack, production-ready deployment.&lt;/p&gt;

&lt;p&gt;Cheers!&lt;/p&gt;

</description>
      <category>deployment</category>
      <category>vps</category>
      <category>webdev</category>
      <category>fullstack</category>
    </item>
    <item>
      <title>Designing Print-Ready Components in Your Web App</title>
      <dc:creator>Joseph01</dc:creator>
      <pubDate>Wed, 05 Jun 2024 21:02:01 +0000</pubDate>
      <link>https://forem.com/joseph42a/designing-print-ready-components-in-your-web-app-3i00</link>
      <guid>https://forem.com/joseph42a/designing-print-ready-components-in-your-web-app-3i00</guid>
      <description>&lt;p&gt;In many web applications, there comes a time when you need to add print functionality. Whether it's for printing invoices, reports, or any other custom components, having a seamless and efficient print solution is crucial. In this blog post, I'll demonstrate how to handle printing in your Vue.js application. The approach we'll cover is also applicable to other frameworks, enabling you to design your print components directly in Vue and print them without the need for manual HTML and CSS in a custom script tag.&lt;/p&gt;

&lt;h2&gt;
  
  
  Approach Explanation
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Add Specific Route for Print: Create a dedicated route for your print component to ensure it opens in a new window with the correct context.&lt;/li&gt;
&lt;li&gt;Design Your Print Component: Style your print component with all necessary elements, ensuring it appears exactly as desired for printing.&lt;/li&gt;
&lt;li&gt;Open Print Page in New Window: Use JavaScript to open the print route in a new window, providing a seamless transition for users.&lt;/li&gt;
&lt;li&gt;Print the Component on Mounted: Trigger the print function directly once the component is mounted, ensuring the print dialog appears immediately.&lt;/li&gt;
&lt;li&gt;Close the Window After Print: Automatically close the print window after the user completes the print action, enhancing the user experience.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Handling Print in Vue.js
&lt;/h2&gt;

&lt;p&gt;First, let's create a Vue component dedicated to printing. This component will be responsible for rendering the content to be printed and initiating the print action, it is just like a template, The template will contain the content we want to print, including an image and a table with sample data.&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 lang="ts"&amp;gt;
import { DUMMY_DATA } from '@/DUMMY';
import { ref, watch } from 'vue';

/**
 * This Component is only for printing
 * Design  in vuejs and print what you see
 */

const imageLoaded = ref(false);

// Once header image loaded print &amp;amp; close window
watch(imageLoaded, () =&amp;gt; {
  window.print();
  window.close();
});
&amp;lt;/script&amp;gt;

&amp;lt;template&amp;gt;
  &amp;lt;Teleport to="body"&amp;gt;
    &amp;lt;div class="modal" style="position: absolute; top: 0; left: 0; width: 100%"&amp;gt;
      &amp;lt;div id="printContainer" style="background-color: white"&amp;gt;
        &amp;lt;table style="width: 100%"&amp;gt;
          &amp;lt;thead&amp;gt;
            &amp;lt;tr&amp;gt;
              &amp;lt;td colspan="7" class="invoice-header"&amp;gt;
                &amp;lt;div class="header-container"&amp;gt;
                  &amp;lt;div&amp;gt;
                    &amp;lt;img
                      width="100"
                      src="@/assets/logo.svg"
                      @load="imageLoaded = true"
                    /&amp;gt;
                  &amp;lt;/div&amp;gt;
                  &amp;lt;h1&amp;gt;Your Company&amp;lt;/h1&amp;gt;
                  &amp;lt;h3&amp;gt;Your Address&amp;lt;/h3&amp;gt;
                &amp;lt;/div&amp;gt;
              &amp;lt;/td&amp;gt;
            &amp;lt;/tr&amp;gt;
            &amp;lt;tr&amp;gt;
              &amp;lt;th&amp;gt;Product&amp;lt;/th&amp;gt;
              &amp;lt;th&amp;gt;Unit Price&amp;lt;/th&amp;gt;
              &amp;lt;th&amp;gt;Amount&amp;lt;/th&amp;gt;
              &amp;lt;th&amp;gt;Total Price&amp;lt;/th&amp;gt;
            &amp;lt;/tr&amp;gt;
          &amp;lt;/thead&amp;gt;

          &amp;lt;tbody&amp;gt;
            &amp;lt;tr v-for="item in DUMMY_DATA" :key="item.id"&amp;gt;
              &amp;lt;td&amp;gt;{{ item.product }}&amp;lt;/td&amp;gt;
              &amp;lt;td&amp;gt;{{ item.unitPrice }}&amp;lt;/td&amp;gt;
              &amp;lt;td&amp;gt;{{ item.amount }}&amp;lt;/td&amp;gt;
              &amp;lt;td&amp;gt;{{ item.totalPrice }}&amp;lt;/td&amp;gt;
            &amp;lt;/tr&amp;gt;
          &amp;lt;/tbody&amp;gt;
        &amp;lt;/table&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/Teleport&amp;gt;
&amp;lt;/template&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here I've a table that I want to display some data, note that I've used an image in my invoice, so the approach is directly printing the opened window, inorder to make sure image is loaded I've added a simple state to indicate image is loaded or not, so only print after image is completly loaded, you can omit this if you don't have image on your template and directly onMounted the component print that window.&lt;/p&gt;

&lt;p&gt;Also note that I use Teleport to move the content to the body for printing.&lt;/p&gt;

&lt;p&gt;And here is the important part which is CSS specific styles for printing&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;style&amp;gt;
/* General print styles here  */
#printContainer {
  table {
    width: 100%;
    border-collapse: collapse;
    break-inside: auto;
    page-break-inside: auto;
  }
  .header-container {
    display: flex;
    justify-content: space-between;
    align-items: center;
  }

  table td,
  table th {
    padding: 1.5mm;
    border: 2px solid #ccc;
    border: 2px solid #ccc;
    vertical-align: top;
    font-size: inherit;
  }
  table td.invoice-header {
    border: none;
  }

  table th {
    text-align: left;
    vertical-align: bottom;
    color: rgb(0, 0, 30);
    background-color: #04aa6d;
  }

  tr:nth-child(even) {
    background-color: #f2f2f2;
  }

  tr:hover {
    background-color: #ddd;
  }

  thead {
    display: table-header-group;
  }
  tfoot {
    display: table-footer-group;
  }
  tr {
    page-break-inside: avoid;
    page-break-after: auto;
  }
  table td,
  table th,
  table tr {
    /* Prevent elements from being split across pages in paginated media (like print) */
    break-inside: avoid;
    /* Automatically insert a page break after the element, if needed */
    break-after: auto;
  }
}
/* Apply styles only when the document is being printed */
@media print {
  /* Apply styles to the printed page */
  @page {
    size: auto;
    /* Set the page margins, hide default header and footer */
    margin: 0.15in 0.3in 0.15in 0.3in !important;
  }

  body {
    /* Ensure that colors are printed exactly as they appear on the screen */
    print-color-adjust: exact;
    -webkit-print-color-adjust: exact;
  }
}
&amp;lt;/style&amp;gt;

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Importance of Print-Specific Styles
&lt;/h2&gt;

&lt;p&gt;When implementing print functionality in your web application, it's essential to define specific styles that ensure your content is presented correctly when printed. Here, we'll discuss the crucial styles used in our Vue.js print component and their importance in achieving a high-quality printed output.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; table {
    width: 100%;
    border-collapse: collapse;
    break-inside: auto;
    page-break-inside: auto;
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;break-inside: auto;&lt;/code&gt; &lt;code&gt;page-break-inside: auto;&lt;/code&gt; Prevents elements from being split across pages.&lt;/p&gt;

&lt;h2&gt;
  
  
  Repeat the header and footer when printing
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;thead {
  display: table-header-group;
}
tfoot {
  display: table-footer-group;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;display: table-header-group;&lt;/code&gt; &lt;code&gt;display: table-footer-group;&lt;/code&gt; Ensures the table headers and footers are repeated on each printed page.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prevent split rows across pages
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tr {
  page-break-inside: avoid;
  page-break-after: auto;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;page-break-inside: avoid;&lt;/code&gt; Prevents rows from being split across pages.&lt;br&gt;
&lt;code&gt;page-break-after: auto;&lt;/code&gt; Automatically inserts a page break after the row if needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Print Media Query
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@media print {
  @page {
    size: auto;
    margin: 0.15in 0.3in 0.15in 0.3in !important;
  }

  body {
    print-color-adjust: exact;
    -webkit-print-color-adjust: exact;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Remove default header and footer when printing
&lt;/h2&gt;

&lt;p&gt;Using margin on printed page we can hide the default header and footer of the page, here is the worked value for me is  &lt;code&gt;margin: 0.15in 0.3in 0.15in 0.3in&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Print exact colors in the page
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;print-color-adjust: exact; -webkit-print-color-adjust: exact;&lt;/code&gt; Ensures that colors are printed exactly as they appear on the screen, maintaining the intended design.&lt;/p&gt;

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

&lt;p&gt;In this article, we've covered how to handle printing in your Vue.js application by defining print-specific styles and ensuring components are print-friendly. This approach, applicable to other frameworks as well, helps create a seamless print experience. Key elements include setting appropriate print styles, managing page breaks, and ensuring color accuracy. For a complete working sample and detailed implementation, check out the &lt;a href="https://github.com/Joseph42A/Printing-with-VueJS" rel="noopener noreferrer"&gt;GitHub repository&lt;/a&gt;. Thank you for reading!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>print</category>
      <category>frontend</category>
      <category>javascript</category>
    </item>
    <item>
      <title>JavaScript Closures in Action: Real-World Applications</title>
      <dc:creator>Joseph01</dc:creator>
      <pubDate>Sun, 05 May 2024 17:12:47 +0000</pubDate>
      <link>https://forem.com/joseph42a/javascript-closures-in-action-real-world-applications-4h6i</link>
      <guid>https://forem.com/joseph42a/javascript-closures-in-action-real-world-applications-4h6i</guid>
      <description>&lt;p&gt;If you just started out learning javascript and spends a few month with it, or even if you've used javascript for a while, chances are you probably didn't face an issue that required knowledge of javascript closure, or actually maybe behind the scene you already used closure without realizing it.&lt;/p&gt;

&lt;p&gt;Closures are considered an advanced topic in javascript, understanding closures is crucial for writing more complex and efficient JavaScript code, let's start to learn more about it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding Closures
&lt;/h2&gt;

&lt;p&gt;Closures occur when a function is defined within another function (the outer function) and has access to variables from the outer function's scope.&lt;/p&gt;

&lt;p&gt;As we all know functions in javascript have access to variables outside of their scope.&lt;br&gt;
&lt;/p&gt;

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

 const add = (a, b) =&amp;gt; {
     return a + b + c; 
 }

 console.log(add(1,1))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see we accessed variable 'c' even though it is outside of &lt;code&gt;add&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;When javascript first created it didn't support classes, so at that time developers used &lt;strong&gt;factory function&lt;/strong&gt; which is a function that returns an object not a value, here is a simple example of factory function&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function createCounter(){
    let value = 0;

    function increment(){
        return ++value
    }

    return {
        increment    
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's create a couple of counters to see what is going on&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const counter1 = createCounter();
const counter2 = createCounter();

console.log(counter1.increment()); // 1
console.log(counter1.increment()); // 2
console.log(counter2.increment()); // 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now as you see each counter has its own value and keep tracks of it, but how is javascript doing that?! the answer is &lt;strong&gt;closure&lt;/strong&gt;, closure tells us &lt;code&gt;increment()&lt;/code&gt; function has access to &lt;code&gt;value&lt;/code&gt; variable, but remember each time &lt;code&gt;createCounter()&lt;/code&gt; get called we're creating a new &lt;code&gt;value&lt;/code&gt; variable so each time &lt;code&gt;incrment()&lt;/code&gt; will get access to its own copy of a &lt;code&gt;value&lt;/code&gt; variable. &lt;/p&gt;

&lt;p&gt;So we can just call  closure &lt;strong&gt;HIDDEN STATE&lt;/strong&gt;, and ofcourse its pretty usefull in object oriented programming.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementing Memoization Funciton with Closure
&lt;/h2&gt;

&lt;p&gt;One of the core concept of web or programming in general is memoization, it is also a technique that applied in dynamic programming, basically memoization is realy just a fancy word for caching, so we are just caching the result of the function so that we don't excute the function if we know the result.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const add = (a, b) =&amp;gt; {
    return a + b;
}

add(1,2); // Excute
add(1,2); // Excute
add(2,2); // Excute
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Normally when we call a function javascript will not cache the result for you, it is just calling and excute the function but if we add a memoizaiton it will only excute when the result is changing, &lt;/p&gt;

&lt;p&gt;So here is the solution of creating a memoization function that takes a function as its argument and handle the &lt;strong&gt;HIDDEN STATE&lt;/strong&gt; (closure) to track the result of the function's excustion&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function memoize (fn){
    let cache = {}
    return function(...args){
        const key = JSON.stringify(args);
        if(key in cache) {
            return cache[key]
        }
        cache[key] = fn(...args);
        return cache[key]
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We used &lt;code&gt;cache&lt;/code&gt; variable as a &lt;strong&gt;HIDDEN STATE&lt;/strong&gt; and stored the function parameters as key and result of the function as the value in a &lt;strong&gt;Hash Map&lt;/strong&gt;, with that we can use our memoize function like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const add = memoize((a, b) =&amp;gt; {
    return a + b;
})

console.log(add(1,2)); // Excute
console.log(add(1,2)); // Doesn't Excute
console.log(add(2,2)); // Excute
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;In conclusion, closures are a powerful and often misunderstood concept in JavaScript. They allow functions to retain access to variables from their lexical scope, even after the outer function has finished executing. Closures are essential for creating private variables, implementing function factories, and optimizing code through techniques like memoization. Understanding closures is crucial for writing more complex and efficient JavaScript code.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Structure Your Project Standartly</title>
      <dc:creator>Joseph01</dc:creator>
      <pubDate>Tue, 13 Feb 2024 17:55:09 +0000</pubDate>
      <link>https://forem.com/joseph42a/structure-your-project-standartly-enough-classic-ways-655</link>
      <guid>https://forem.com/joseph42a/structure-your-project-standartly-enough-classic-ways-655</guid>
      <description>&lt;p&gt;So, you're writing code &amp;amp; building projects one after another, there is the possibility that you just don't care about how you structure your projects, the thing that matters is finishing the project delivering a feature, or completing a task.&lt;/p&gt;

&lt;p&gt;But, after a while, you left the project then came back, and boom!! You don't know what is going on (especially if the project you built is a little bit) you may spend days to reunderstand the project, which happens to almost all new developers especially self-taught ones unless you are blessed by a good mentor to clear the way you'll go through in the future.&lt;/p&gt;

&lt;p&gt;It is now time to revamp the way you structure your project, this will show your projects stand out from those who mess up even the small-sized projects, in this blog I will discuss two approaches that are very useful and standard for you to build scalable and maintainable projects, as well as discuss avoid &lt;strong&gt;No-Approach&lt;/strong&gt; way of structuring your project, but first let's understand what is the Frontend Architecture.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frontend Architecture
&lt;/h2&gt;

&lt;p&gt;Frontend architecture refers to how the code of an application is organized and structured. It outlines how different modules within the system communicate with one another, defines the interfaces of individual modules, and prescribes best practices for their development.&lt;/p&gt;

&lt;p&gt;An effective front-end architecture is essential for maintaining a manageable and comprehensible codebase. It significantly streamlines the process of implementing new features, refactoring existing code, and preventing unexpected errors. The optimal architecture comprises modules that are loosely interconnected and closely aligned in purpose&lt;/p&gt;

&lt;h2&gt;
  
  
  Avoid Classical Structure Approach
&lt;/h2&gt;

&lt;p&gt;If you still don't know what is the classic approach to avoid it, how it look like! actually there is no specific rules for it, if you follow youtube tutorial projects, most of them(if not all) are using that way because it is simple and easy to comeup with, it typically looks like this&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%2F601szpc7i47g9deq3zar.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%2F601szpc7i47g9deq3zar.png" alt=" " width="397" height="623"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There is a lot of problems with this approach, like navigating through the project becomes challenging due to poor organization, making it difficult to locate components and comprehend their relationships within the codebase. As a result, the learning curve for new developers steepens significantly, requiring an extended period to familiarize themselves with the project's intricacies. Maintenance becomes an arduous task over time, compounded by the accumulation of code complexity and the presence of unexpected bugs stemming from subpar code quality. Ultimately, these factors contribute to prolonged feature delivery timelines, impeding the project's overall progress and efficiency.&lt;/p&gt;

&lt;p&gt;It is fine to use this approach if your project doesn't need future updates or maintenance, or simple project, otherwise there is no reason for using this appreaoch.&lt;/p&gt;

&lt;h2&gt;
  
  
  Modular Approach
&lt;/h2&gt;

&lt;p&gt;One alternative approach or structure for the classic approach is using the module approach for your small or medium-sized project since it is easy to understand also using this will prepare you for an advanced approach for a large code basis which is FSD(we'll have a look next).&lt;/p&gt;

&lt;p&gt;In most cases, it consists of only four parts: pages, modules, components, and UI.&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%2Fei7uwhfcfvbx41etbs6m.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%2Fei7uwhfcfvbx41etbs6m.png" alt=" " width="800" height="441"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;UI: This directory contains UI components like buttons, selects, and inputs.&lt;/li&gt;
&lt;li&gt;Components: This directory houses less independent pieces of code, such as ProductCard. However, items within this directory should not contain specific business logic to ensure high reusability.&lt;/li&gt;
&lt;li&gt;Modules: This directory is designated for independent modules of the application. For instance, SignInForm serves as an isolated module with its own logic and objectives.&lt;/li&gt;
&lt;li&gt;Pages: This directory manages the application routes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Overall, this approach surpasses the "Classical" one, offering a more robust structure. Its benefits are evident and pronounced:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enhanced project navigation, simplifying the discovery of components, functions, and more.&lt;/li&gt;
&lt;li&gt;Clear and intuitive structure, facilitating ease of understanding.&lt;/li&gt;
&lt;li&gt;Reduced coupling and increased cohesion within the system.&lt;/li&gt;
&lt;li&gt;Improved maintenance and scalability.&lt;/li&gt;
&lt;li&gt;Expedited feature delivery resulting from significantly enhanced developer experience.&lt;/li&gt;
&lt;li&gt;Accommodation for larger developer teams, enabling seamless collaboration.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While this approach offers clear advantages, it may not be ideal for extensive and intricate projects. Managing a large volume of features and business logic can pose challenges within this architecture.&lt;/p&gt;

&lt;h2&gt;
  
  
  Feature Sliced Design (FSD)
&lt;/h2&gt;

&lt;p&gt;Feature Sliced Design stands out as one of the most contemporary and dependable architectural paradigms crafted specifically for front-end projects. It seamlessly adapts to various business scenarios, addresses common challenges, and offers an intuitive experience for newcomers to development.&lt;/p&gt;

&lt;p&gt;In "Feature Sliced Design," a project is structured into layers, with each layer comprising slices, and each slice containing segments. Before delving deeper into the intricacies of layers, slices, and segments, it's beneficial to first gain a broad understanding of the overall framework.&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%2Fg0bfpsh49zp80jub2ts4.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%2Fg0bfpsh49zp80jub2ts4.png" alt=" " width="800" height="437"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The top-level folders of "Feature Sliced Design" are referred to as "Layers," constituting the initial level of application segmentation. These layers adhere to a predefined set, some of which are optional. Currently, there are seven standardized layers:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Shared Layer: This encompasses reusable functionalities independent of business logic, such as UI-kit components, helpers, and loggers.&lt;/li&gt;
&lt;li&gt;Entities Layer: Here reside the project-specific business entities, such as User, Payments, and Products.&lt;/li&gt;
&lt;li&gt;Feature Layer: Comprising user stories and code that directly adds business value, like ChangePassword or MakePayment functionalities.&lt;/li&gt;
&lt;li&gt;Widgets Layer: Housing components that amalgamate entities and features, facilitating the creation of composite elements like UserSettings or PaymentsList.&lt;/li&gt;
&lt;li&gt;Pages Layer: This layer constitutes the application pages, crafted by combining entities, features, and widgets to create comprehensive user interfaces.&lt;/li&gt;
&lt;li&gt;Processes Layer: Hosting complex inter-page scenarios, such as authentication and captcha functionalities.&lt;/li&gt;
&lt;li&gt;App Layer: Serving as the repository for application settings, styles, and providers, exemplified by components like withAuth HOC.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Feature Sliced Design&lt;/strong&gt; offers numerous advantages that make it a highly favorable choice. It outperforms other approaches across various aspects. Here are the main pros:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Business and User-Centric: The architecture is structured around fulfilling business requirements and user needs effectively.&lt;/li&gt;
&lt;li&gt;Controlled Logic Reusability: It promotes the systematic reuse of logic, ensuring efficient utilization across different parts of the application.&lt;/li&gt;
&lt;li&gt;Resilience to Changes: The design maintains stability even in the face of frequent changes and refactoring, minimizing disruptions to the development process.&lt;/li&gt;
&lt;li&gt;Scalability: It exhibits high scalability both in terms of architectural growth and team expansion, accommodating project evolution and increased workforce seamlessly.&lt;/li&gt;
&lt;li&gt;Incremental Adoption: "Feature Sliced Design" allows for gradual integration and adoption, enabling teams to transition smoothly without major overhauls.&lt;/li&gt;
&lt;li&gt;Technology Stack Agnostic: It offers independence from specific technological stacks, allowing flexibility in choosing tools and frameworks best suited for the project.&lt;/li&gt;
&lt;li&gt;Standardization: The architecture promotes uniformity and consistency, facilitating ease of understanding, maintenance, and collaboration among team members.&lt;/li&gt;
&lt;li&gt;Comprehensive Documentation and Support: With robust documentation and a thriving community, "Feature Sliced Design" ensures accessibility to resources and assistance for developers.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Neglecting project structure in favor of rapid feature delivery can lead to significant challenges in the long term. Returning to a disorganized codebase can be daunting, particularly for new developers, and can hinder maintenance and scalability efforts. By adopting a modular approach or embracing the Feature Sliced Design architecture, developers can ensure their projects are scalable, maintainable, and adaptable to future changes. Prioritizing project structure not only enhances developer productivity but also improves code quality, streamlines maintenance efforts, and ultimately leads to more successful and sustainable projects.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>architecture</category>
      <category>programming</category>
      <category>development</category>
    </item>
    <item>
      <title>Nextjs Page Transition With Framer-Motion</title>
      <dc:creator>Joseph01</dc:creator>
      <pubDate>Sun, 28 Jan 2024 22:14:51 +0000</pubDate>
      <link>https://forem.com/joseph42a/nextjs-page-transition-with-framer-motion-33dg</link>
      <guid>https://forem.com/joseph42a/nextjs-page-transition-with-framer-motion-33dg</guid>
      <description>&lt;p&gt;Creating seamless and visually engaging transitions between pages has become an integral aspect of enhancing user experience. Next.js, a popular React framework, offers a powerful combination with Framer Motion, a declarative motion library for React, to bring life to page transitions, let's get started.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup The Project
&lt;/h2&gt;

&lt;p&gt;Create a nextjs project by running this 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 create-next-app@latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will fire the nextjs project with the latest release (in my case is version 14.1.0), feel free to set up your next project as you want, I'm going to use typescript with app router, and tailwinds for styling, clean up the root page &lt;code&gt;app/page.tsx&lt;/code&gt; from the nextjs starter page, mine is like this&lt;/p&gt;

&lt;p&gt;&lt;code&gt;app/page.tsx&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;export default function Home() {
  return (
    &amp;lt;section className="p-4"&amp;gt;
      &amp;lt;div className="container"&amp;gt;
        &amp;lt;h1 className="text-2xl font-bold"&amp;gt;Home Page&amp;lt;/h1&amp;gt;
        &amp;lt;p className="w-1/2 font-medium py-2"&amp;gt;
          Lorem ipsum dolor sit amet consectetur adipisicing elit. Molestias
          natus minima exercitationem perferendis hic maxime nihil officia
          fugit, illo asperiores fugiat odit harum, dicta cumque ad atque
          assumenda! Saepe dolores repellendus animi harum ex voluptatibus
          quaerat unde obcaecati quo consequuntur sequi, autem deleniti?
          Eligendi ipsa impedit cupiditate accusantium delectus quidem.
        &amp;lt;/p&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/section&amp;gt;
  );
}

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

&lt;/div&gt;



&lt;p&gt;Also, I'm going to add two more pages with the same content to the animation to look cleaner, &lt;code&gt;app/about/page.tsx&lt;/code&gt; and &lt;code&gt;app/contact/page.tsx&lt;/code&gt;, and add a header component for simple navigation between the pages &lt;code&gt;header.tsx&lt;/code&gt; and use it in the layout&lt;br&gt;
&lt;code&gt;header.tsx&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;import Link from "next/link";

export default function Header() {
  return (
    &amp;lt;header&amp;gt;
      &amp;lt;nav className="p-4"&amp;gt;
        &amp;lt;ul className="container flex gap-8"&amp;gt;
          &amp;lt;li&amp;gt;
            &amp;lt;Link href="/"&amp;gt;Home&amp;lt;/Link&amp;gt;
          &amp;lt;/li&amp;gt;
          &amp;lt;li&amp;gt;
            &amp;lt;Link href="/about"&amp;gt;About&amp;lt;/Link&amp;gt;
          &amp;lt;/li&amp;gt;
          &amp;lt;li&amp;gt;
            &amp;lt;Link href="/contact"&amp;gt;Contact&amp;lt;/Link&amp;gt;
          &amp;lt;/li&amp;gt;
        &amp;lt;/ul&amp;gt;
      &amp;lt;/nav&amp;gt;
    &amp;lt;/header&amp;gt;
  );
}

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Add Framer Motion
&lt;/h2&gt;

&lt;p&gt;To install framer-motion simply run the command below&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install framer-motion
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now after installing the &lt;strong&gt;framer-motion&lt;/strong&gt; we gonna create a &lt;code&gt;Transition.tsx&lt;/code&gt; component to define our base page transition using framer-motion, hers is the code for that component&lt;br&gt;
&lt;/p&gt;

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

import { motion } from "framer-motion";

export default function Transition({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    &amp;lt;motion.div
      initial={{ y: 20, opacity: 0 }}
      animate={{ y: 0, opacity: 1 }}
      transition={{ ease: "easeInOut", duration: 0.75 }}
    &amp;gt;
      {children}
    &amp;lt;/motion.div&amp;gt;
  );
}

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

&lt;/div&gt;



&lt;p&gt;As you can see this component is a client component so we marked it as a client component using &lt;code&gt;use client&lt;/code&gt; on top of the component declaration, basically we're using &lt;code&gt;motion&lt;/code&gt; from &lt;code&gt;framer-motion&lt;/code&gt; and using initial, animate, and transition props we can define the page animation. &lt;/p&gt;

&lt;h2&gt;
  
  
  Using Nextjs Template To Render Animation Pages
&lt;/h2&gt;

&lt;p&gt;You may ask why we can't just use &lt;code&gt;Layout.tsx&lt;/code&gt; to wrap our pages with the &lt;code&gt;Transition.tsx&lt;/code&gt; component, Just like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
import Header from "./header";
import Transition from "./trasnition";

const inter = Inter({ subsets: ["latin"] });

export const metadata: Metadata = {
  title: "Page Transition",
  description: "Using framer-motion to add trasition between pages",
};

export default function RootLayout({
  children,
}: Readonly&amp;lt;{
  children: React.ReactNode;
}&amp;gt;) {
  return (
    &amp;lt;html lang="en"&amp;gt;
      &amp;lt;body className={inter.className}&amp;gt;
        &amp;lt;Header /&amp;gt;
        &amp;lt;Transition&amp;gt;{children}&amp;lt;/Transition&amp;gt;
      &amp;lt;/body&amp;gt;
    &amp;lt;/html&amp;gt;
  );
}

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

&lt;/div&gt;



&lt;p&gt;The problem is you can only see the animation for the first render (initial load), then, if you navigate to other pages, Nextjs will not rerender those pages from the &lt;code&gt;layout&lt;/code&gt;, so that the Transition will not render for that page, So, for that case &lt;code&gt;Template.tsx&lt;/code&gt; comes as a handy solution, here is the definition of &lt;code&gt;Template&lt;/code&gt; from Nextjs doc&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Unlike layouts that persist across routes and maintain state, templates create a new instance for each of their children on navigation. This means that when a user navigates between routes that share a template, a new instance of the component is mounted, DOM elements are recreated, state is not preserved, and effects are re-synchronized.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now create &lt;code&gt;template.tsx&lt;/code&gt; under the app directory, and copy paste the code from the &lt;code&gt;Transition.tsx&lt;/code&gt; component, and rename the component name to Template(), like 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 client";

import { motion } from "framer-motion";

export default function Template({ children }: { children: React.ReactNode }) {
  return (
    &amp;lt;motion.div
      initial={{ y: 20, opacity: 0 }}
      animate={{ y: 0, opacity: 1 }}
      transition={{ ease: "easeInOut", duration: 0.75 }}
    &amp;gt;
      {children}
    &amp;lt;/motion.div&amp;gt;
  );
}

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

&lt;/div&gt;



&lt;p&gt;And here you go! we have added the page transition for the project, you can customize the transition the way you want, and have a better experience, if you have any questions feel free to ask.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Joseph42A/nextjs-page-transition-framer-motion" rel="noopener noreferrer"&gt;Github Source Code&lt;/a&gt;&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>nextjs</category>
      <category>animation</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How To Grow As a Frontend Developer in 2024</title>
      <dc:creator>Joseph01</dc:creator>
      <pubDate>Sat, 06 Jan 2024 14:17:56 +0000</pubDate>
      <link>https://forem.com/joseph42a/how-to-grow-as-a-frontend-developer-in-2024-1j46</link>
      <guid>https://forem.com/joseph42a/how-to-grow-as-a-frontend-developer-in-2024-1j46</guid>
      <description>&lt;p&gt;As we step into 2024, the realm of frontend development continues its rapid evolution, demanding a proactive approach to growth and skill enhancement. With over three years of experience in the field, I've come to realize the paramount importance of continually expanding one's skill set and staying abreast of the latest advancements in the industry.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Mastering Core Technologies&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Revisiting the core trio of HTML, CSS, and JavaScript remains a cornerstone of frontend development. As a seasoned frontend developer, honing these foundational skills is a perpetual process, ensuring a solid understanding of the building blocks upon which all frontend technologies are constructed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Exploring Advanced Frameworks and Libraries&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Delving into advanced frontend frameworks such as React, Vue.js, or Angular is pivotal in keeping pace with the ever-evolving ecosystem. As a frontend developer committed to growth, staying updated with the latest features and updates of these frameworks remains a priority.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Version Control Systems and Collaboration Tools&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the collaborative landscape of development, proficiency in version control systems like Git and collaborative platforms such as GitHub is indispensable. Understanding these tools' nuances and leveraging them for efficient teamwork has been instrumental in my growth as a frontend developer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Continuous Learning and Adaptability&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Embracing a growth mindset and continually adapting to emerging technologies and trends is a philosophy that has driven my career progression. The frontend domain's dynamic nature demands adaptability and a hunger for learning, traits I actively cultivate in my professional journey.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Soft Skills and Professional Development&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Recognizing the significance of soft skills alongside technical prowess has been pivotal in my career growth. Effective communication, teamwork, and problem-solving are indispensable skills that complement technical expertise and contribute to overall professional development.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Building Projects and Contributions&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Fostering personal projects, contributing to open-source initiatives, and nurturing a robust portfolio have been an ongoing endeavor. Showcasing skills through practical implementations and real-world contributions has been a testament to my dedication to growth and learning.&lt;/p&gt;

&lt;p&gt;As I conclude this reflection on growth as a frontend developer in 2024, it's clear that the journey to mastery is an ongoing expedition rather than a destination. Embracing a growth-oriented mindset, staying passionate about learning, and continually adapting to the ever-changing landscape remain my guiding principles in this exciting field.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>frontend</category>
      <category>javascript</category>
      <category>programming</category>
    </item>
    <item>
      <title>Practical Applications of the Next.js 14 Image Component: Hands-on Examples</title>
      <dc:creator>Joseph01</dc:creator>
      <pubDate>Thu, 14 Dec 2023 20:24:02 +0000</pubDate>
      <link>https://forem.com/joseph42a/practical-applications-of-the-nextjs-14-image-component-hands-on-examples-3753</link>
      <guid>https://forem.com/joseph42a/practical-applications-of-the-nextjs-14-image-component-hands-on-examples-3753</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In today's web development landscape, optimizing images is pivotal for performance and user experience. While Next.js offers an Image component for image optimization, crafting a reusable image solution tailored to specific application needs proves invaluable.&lt;/p&gt;

&lt;p&gt;This blog explores the significance of a customizable image component beyond Next.js' defaults. We'll dive into the benefits of creating a bespoke image component, enabling versatile image handling for diverse use cases in Next.js applications. Let's uncover how this customizable approach enhances image management, elevates user experience, and optimizes performance across Next.js projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting Up Next.js &amp;amp; Required Libraries
&lt;/h2&gt;

&lt;p&gt;You can easily create nextjs app in my time 14 by running&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx create-next-app@latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I'll stick with javascript and tailwindcss, feel free to use typescript if you want, I'll provide repo link at the end.&lt;/p&gt;

&lt;p&gt;After creating your project, we have to install three more libraries that we need for the image component that we gonna create&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install sharp plaiceholder @plaiceholder/next
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We need these packages to convert our images to base64 for blurDataUrl the next image component requires us when we want to use external images.&lt;/p&gt;

&lt;p&gt;Since we are using remote images from a remote source, in my case I will use Unsplash, so we have to add Unsplash image API into next config remotePatterns, as well as add the image formats&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const nextConfig = {
  images: {
    formats: ["image/avif", "image/webp"],
    remotePatterns: [
      {
        hostname: "images.unsplash.com",
      },
    ],
  },
};

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Creating a Reusable Image Component
&lt;/h2&gt;

&lt;p&gt;Our image component is very simple you can copy and paste the code below, I named BaseImage since it will be my base Image component throughout my project&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"use client";
import React, { useState } from "react";
import placeholderImage from "@/assets/placeholder.jpg";
import Image from "next/image";
import defaultBlur from "@/assets/blurData";

export default function BaseImage({ src, width, height, blurData, ...rest }) {
  const [imgSrc, setImgSrc] = useState(src);

  return (
    &amp;lt;Image
      src={imgSrc}
      width={width}
      height={height}
      placeholder="blur"
      blurDataURL={!!blurData ? blurData : defaultBlur}
      onError={() =&amp;gt; {
        setImgSrc(placeholderImage);
      }}
      {...rest}
    /&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that the component is a client component because we are using a state to set the fallback src image, and we're passing the blurData of a remote image that we gonna use, notice we also have a default blur data, case remote image has some problem to access it we will show our fallback blur data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating base64 util function
&lt;/h2&gt;

&lt;p&gt;Before we use our &lt;code&gt;BaseImage&lt;/code&gt; component, we have to add a function that takes our remote source and returns a base64 of that image so then we'll be able to use that as a blurDataUrl for that image, here is the implementation&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { unstable_noStore } from "next/cache";
import { getPlaiceholder } from "plaiceholder";

async function getBlurData(src) {
  unstable_noStore();
  try {
    const buffer = await fetch(src).then(async (res) =&amp;gt; {
      return Buffer.from(await res.arrayBuffer());
    });

    const data = await getPlaiceholder(buffer);
    return data;
  } catch (err) {
    console.error("Error fetching or processing image:", err);
    return { base64: "", img: "" };
  }
}

export { getBlurData };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that the function I created under the root of app/lib/utils.js because the &lt;code&gt;plaiceholder&lt;/code&gt; package is working under the nodejs environment so we have to put it under the app directory.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example: Implementing in a Card Component
&lt;/h2&gt;

&lt;p&gt;Here is an example of how to use our image component with a grid card container&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { getBlurData } from "@/app/lib/utils";

import React from "react";
import BaseImage from "./BaseImage";
import Link from "next/link";

const data = [
  {
    id: 1,
    title: "Cat 1",
    description:
      "Cat 1 is a playful and energetic feline who loves to explore and chase toys around the house.",
    imgSrc:
      "https://images.unsplash.com/photo-1646753522408-077ef9839300?ixlib=rb-1.2.1&amp;amp;ixid=MnwxMjA3fDB8MHxwcm9maWxlLXBhZ2V8NjZ8fHxlbnwwfHx8fA%3D%3D&amp;amp;auto=format&amp;amp;fit=crop&amp;amp;w=500&amp;amp;q=60",
  },
  {
    id: 2,
    title: "Cat 2",
    description:
      "Cat 2 is a calm and affectionate furry friend who enjoys lounging in cozy spots and getting cuddles.",
    imgSrc:
      "https://images.unsplash.com/photo-1651950519238-15835722f8bb?ixlib=rb-1.2.1&amp;amp;ixid=MnwxMjA3fDB8MHxwcm9maWxlLXBhZ2V8Mjh8fHxlbnwwfHx8fA%3D%3D&amp;amp;auto=format&amp;amp;fit=crop&amp;amp;w=500&amp;amp;q=60",
  },
  {
    id: 3,
    title: "Cat 3",
    description:
      "Cat 3 is an adventurous and curious cat who loves exploring the outdoors and climbing trees.",
    imgSrc:
      "https://images.unsplash.com/photo-1651950537598-373e4358d320?ixlib=rb-1.2.1&amp;amp;ixid=MnwxMjA3fDB8MHxwcm9maWxlLXBhZ2V8MjV8fHxlbnwwfHx8fA%3D%3D&amp;amp;auto=format&amp;amp;fit=crop&amp;amp;w=500&amp;amp;q=60",
  },
  // This is for an error image
  // {
  //   id: 4,
  //   title: "Cat 2",
  //   description:
  //     "Cat 3 is an adventurous and curious cat who loves exploring the outdoors and climbing trees.",
  //   imgSrc:
  //     "https://images.unsplash.com/photo-1651950537598-373e4358d3202?ixlib=rb-1.2.1&amp;amp;ixid=MnwxMjA3fDB8MHxwcm9maWxlLXBhZ2V8MjV8fHxlbnwwfHx8fA%3D%3D&amp;amp;auto=format&amp;amp;fit=crop&amp;amp;w=500&amp;amp;q=60",
  // },
];

const Cards = () =&amp;gt; {
  return (
    &amp;lt;section className="w-fit mx-auto grid grid-cols-1 lg:grid-cols-3 md:grid-cols-2 justify-items-center justify-center gap-y-20 gap-x-14 mt-10 mb-5"&amp;gt;
      {data.map((x) =&amp;gt; (
        &amp;lt;Card key={x.id} {...x} /&amp;gt;
      ))}
    &amp;lt;/section&amp;gt;
  );
};

async function Card({ imgSrc, title, description }) {
  const { base64 } = await getBlurData(imgSrc);
  return (
    &amp;lt;div className="bg-white shadow-md rounded-xl duration-500 hover:scale-105 hover:shadow-xl"&amp;gt;
      &amp;lt;Link href="#"&amp;gt;
        &amp;lt;div className="relative h-80"&amp;gt;
          &amp;lt;BaseImage
            blurData={base64}
            src={imgSrc}
            alt={title}
            fill
            sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 30vw"
            className="object-cover rounded-t-xl"
          /&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;div className="px-4 py-3 w-72"&amp;gt;
          &amp;lt;p className="text-lg font-bold text-black truncate block capitalize"&amp;gt;
            {title}
          &amp;lt;/p&amp;gt;
          &amp;lt;div className="flex items-center"&amp;gt;
            &amp;lt;p className="text-lg font-semibold text-gray cursor-auto my-3"&amp;gt;
              {description}
            &amp;lt;/p&amp;gt;
          &amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
      &amp;lt;/Link&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

export default Cards;

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Implementation with Two-Section Layout
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";
import BaseImage from "./BaseImage";
import { getBlurData } from "@/app/lib/utils";

const LAYOUT_URL =
  "https://images.unsplash.com/photo-1465146344425-f00d5f5c8f07";
const TwoSectionLayout = async () =&amp;gt; {
  const { base64 } = await getBlurData(LAYOUT_URL);

  return (
    &amp;lt;section className="text-gray-600 body-font"&amp;gt;
      &amp;lt;div className="w-11/12 max-w-4xl bg-orange-400 grid grid-cols-1 sm:grid-cols-12 mx-auto items-center  px-5 py-24 "&amp;gt;
        &amp;lt;div className="lg:pr-24 md:pr-16 col-span-12 md:col-span-6 md:text-left mb-16 md:mb-0 text-center"&amp;gt;
          &amp;lt;h1 className="title-font sm:text-4xl text-3xl mb-4 font-medium text-gray-900"&amp;gt;
            Before they sold out
            &amp;lt;br className="hidden lg:inline-block" /&amp;gt;
            readme gluten
          &amp;lt;/h1&amp;gt;
          &amp;lt;p className="mb-8 leading-relaxed"&amp;gt;
            Copper mug try-hard pitchfork pour-over freeway heirloom neutral air
            plant cold-pressed tacos poke beard tote bag. Heirloom echo park
            mash tote bag selvage hot chicken authentic tumeric truffaut hexagon
            try-hard chambray.
          &amp;lt;/p&amp;gt;
          &amp;lt;div className=""&amp;gt;
            &amp;lt;button className="inline-flex text-white bg-indigo-500 border-0 py-2 px-6 focus:outline-none hover:bg-indigo-600 rounded text-lg"&amp;gt;
              Button
            &amp;lt;/button&amp;gt;
          &amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;div className="w-full relative  h-[600px] col-span-12 md:col-span-6 "&amp;gt;
          &amp;lt;BaseImage
            fill
            sizes="(min-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
            className="object-cover rounded"
            alt="hero"
            src={LAYOUT_URL}
            blurData={base64}
          /&amp;gt;
        &amp;lt;/div&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/section&amp;gt;
  );
};

export default TwoSectionLayout;

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

&lt;/div&gt;



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

&lt;p&gt;Optimizing images is integral to web development's performance and user appeal. Throughout this exploration, we've emphasized the pivotal role of a tailored image component in Next.js, surpassing default capabilities.&lt;/p&gt;

&lt;p&gt;Github link: &lt;a href="https://github.com/Joseph42A/reusable-nextjs-image-component" rel="noopener noreferrer"&gt;Source Code&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>frontend</category>
      <category>nextjs</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Enhancing Your Next.js App with the Image Component: A Comprehensive Guide</title>
      <dc:creator>Joseph01</dc:creator>
      <pubDate>Mon, 04 Dec 2023 05:03:39 +0000</pubDate>
      <link>https://forem.com/joseph42a/enhancing-your-nextjs-app-with-the-image-component-a-comprehensive-guide-2cg2</link>
      <guid>https://forem.com/joseph42a/enhancing-your-nextjs-app-with-the-image-component-a-comprehensive-guide-2cg2</guid>
      <description>&lt;p&gt;In the realm of web development, Next.js has emerged as a frontrunner, offering a robust framework for building performant and SEO-friendly React applications. Among its many advantages, Next.js provides a dedicated Image component, specifically designed to optimize image rendering and enhance website performance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is the Next.js Image Component?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Next.js Image component is an extension of the standard HTML &lt;a href="" class="article-body-image-wrapper"&gt;&lt;img&gt;&lt;/a&gt; element, tailored to address the challenges of image optimization in modern web development. It leverages a combination of techniques, including image resizing, automatic format selection, and lazy loading, to ensure that images are delivered efficiently and seamlessly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why Use the Next.js Image Component?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There are several compelling reasons to adopt the Next.js Image component in your web development projects:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Image Optimization:&lt;/strong&gt; The component automatically optimizes images for different device sizes and screen resolutions, ensuring that only the appropriate size is loaded for each device, reducing bandwidth usage and improving page load times.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Lazy Loading:&lt;/strong&gt; Lazy loading defers the loading of non-critical images until they are visible in the viewport, further enhancing page load performance. This technique is particularly beneficial for pages with numerous images.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Image Formats:&lt;/strong&gt; The component intelligently selects the most suitable image format based on browser compatibility and file size, optimizing image delivery for different browsers and devices.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. SEO Benefits:&lt;/strong&gt; By optimizing image loading and file sizes, the Image component contributes to improved search engine rankings, as search engines prioritize websites with fast loading times and efficient image handling.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Developer Experience:&lt;/strong&gt; The component simplifies image handling in Next.js applications, providing a consistent and declarative interface for managing images across different pages and components.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How Does the Next.js Image Component Affect Website Performance?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Next.js Image component significantly impacts website performance in several ways:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Reduced Bandwidth Usage:&lt;/strong&gt; By optimizing image sizes and formats, the component minimizes the amount of data transferred, leading to faster loading times and lower bandwidth consumption.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Improved Page Load Times:&lt;/strong&gt; Lazy loading and image optimization techniques contribute to faster page rendering, resulting in a smoother and more responsive user experience.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Enhanced SEO:&lt;/strong&gt; Optimized image handling improves search engine rankings, attracting more organic traffic to your website.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Streamlined Development:&lt;/strong&gt; The component's declarative syntax and automatic optimization reduce development time and simplify image management in Next.js applications.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Implementing the Next.js Image Component&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Integrating the Image component into your Next.js application is straightforward:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Image&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;next/image&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Image&lt;/span&gt;
  &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/path/to/image.jpg"&lt;/span&gt;
  &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1200&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;600&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Image description"&lt;/span&gt;
&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The required props include &lt;code&gt;src&lt;/code&gt;, &lt;code&gt;width&lt;/code&gt;, &lt;code&gt;height&lt;/code&gt;, and &lt;code&gt;alt&lt;/code&gt;. Additionally, you can customize the component's behavior using optional props like &lt;code&gt;loader&lt;/code&gt;, &lt;code&gt;fill&lt;/code&gt;, &lt;code&gt;sizes&lt;/code&gt;, and &lt;code&gt;quality&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real-World Examples&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To illustrate the practical application of the Next.js Image component, consider the following examples:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example 1: Image on Top of Card with Title and Description&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Image&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;next/image&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"card shadow-sm"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Image&lt;/span&gt;
    &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/path/to/image.jpg"&lt;/span&gt;
    &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="na"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Image description"&lt;/span&gt;
  &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Card Title&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Card description.&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Example 2: Image Grid Container with Tailwind CSS Styling&lt;/strong&gt;&lt;br&gt;
You can have a nicely &amp;amp; easily displaing a group of responsive and optimized images with grid&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Image&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;next/image&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"grid grid-cols-3 gap-4 p-6"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"card relative h-[200px]"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Image&lt;/span&gt;
            &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"image"&lt;/span&gt;
            &lt;span class="na"&gt;fill&lt;/span&gt;
            &lt;span class="na"&gt;sizes&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"100vw"&lt;/span&gt;
            &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;objectFit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cover&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
            &lt;span class="na"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Image description"&lt;/span&gt;
          &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"card relative h-[200px]"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Image&lt;/span&gt;
            &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"image"&lt;/span&gt;
            &lt;span class="na"&gt;fill&lt;/span&gt;
            &lt;span class="na"&gt;sizes&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"100vw"&lt;/span&gt;
            &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;objectFit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cover&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
            &lt;span class="na"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Image description"&lt;/span&gt;
          &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"card relative h-[200px]"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Image&lt;/span&gt;
            &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"image"&lt;/span&gt;
            &lt;span class="na"&gt;fill&lt;/span&gt;
            &lt;span class="na"&gt;sizes&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"100vw"&lt;/span&gt;
            &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;objectFit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cover&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
            &lt;span class="na"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Image description"&lt;/span&gt;
          &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These examples demonstrate the versatility of the Next.js Image component in creating visually appealing and performant web applications.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Next.js Image component stands as an invaluable tool for optimizing image rendering and enhancing website performance in Next.js applications. Its ability to automatically optimize images, leverage lazy loading, and select appropriate image formats makes it an essential tool for building performant and SEO-friendly web applications. Embrace the Image component and elevate your Next.js projects to new heights of efficiency and user experience.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>frontend</category>
      <category>nextjs</category>
      <category>react</category>
    </item>
    <item>
      <title>Why Webpack? Exploring Its Role in Web Development</title>
      <dc:creator>Joseph01</dc:creator>
      <pubDate>Fri, 24 Nov 2023 16:55:35 +0000</pubDate>
      <link>https://forem.com/joseph42a/why-webpack-exploring-its-role-in-web-development-4bco</link>
      <guid>https://forem.com/joseph42a/why-webpack-exploring-its-role-in-web-development-4bco</guid>
      <description>&lt;p&gt;Ever found yourself knee-deep in a web development project, juggling JavaScript files, wrestling with CSS dependencies, and wondering why your site's performance resembles rush hour traffic? Trust me, I've been there!&lt;/p&gt;

&lt;p&gt;As a fellow web developer, I've often pondered the same question: What's the deal with Webpack? What sorcery lies behind those configurations and why does it even exist? You know the drill – creating a website from scratch using HTML, CSS, and JavaScript seems like a breeze at first, until your project grows larger and suddenly resembles a tangled ball of yarn. Cue the headache-inducing manual dependency management!&lt;/p&gt;

&lt;p&gt;But fear not, fellow developers! Enter Webpack – the unsung hero of modern web development. It's not just another tool in the shed; it's the Swiss Army knife you've been searching for in the wild wilderness of code chaos.&lt;/p&gt;

&lt;p&gt;Webpack isn't just about bundling modules; it's a game-changer, a guardian angel, if you will, that swoops in to streamline your development workflow, optimize performance, and tame the unruly beast that is web application dependencies.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction to Webpack
&lt;/h2&gt;

&lt;p&gt;At its core, webpack isn't merely a tool; it's a game-changer. It redefines how developers approach organizing and bundling code, offering a robust solution that streamlines development workflows, optimizes performance, and transforms the way web applications are delivered to end-users.&lt;/p&gt;

&lt;p&gt;Webpack functions as the backbone of many modern web projects, taking disparate modules, assets, stylesheets, and scripts, and intelligently bundling them into optimized bundles. But it's not just about bundling; webpack empowers developers by providing a sophisticated ecosystem of loaders, plugins, and optimizations, allowing for tailored and efficient workflows.&lt;/p&gt;

&lt;p&gt;Through its powerful configuration capabilities, webpack orchestrates the transformation of code, optimizing assets, and handling dependencies seamlessly. It simplifies tasks that were once cumbersome, such as code splitting, lazy loading, and tree shaking, ensuring optimal performance and a leaner, more responsive web application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Benefits of Leveraging Webpack in Your Project
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Efficient Module Bundling:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Organized Codebase:&lt;/strong&gt; Webpack facilitates a modular approach, allowing you to split your code into smaller, manageable modules.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dependency Management:&lt;/strong&gt; It creates a dependency graph and bundles these modules efficiently, reducing HTTP requests and optimizing load times.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Performance Optimization:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code Splitting:&lt;/strong&gt; Webpack enables code splitting, allowing for the loading of essential code upfront and fetching additional code as needed, improving initial load times.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Minification &amp;amp; Compression:&lt;/strong&gt; It optimizes JavaScript, CSS, and other assets by minifying and compressing them, reducing file sizes for faster downloads.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Enhanced Development Workflow:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Dev Server &amp;amp; Hot Module Replacement (HMR): Offers a development server with HMR support, allowing for real-time updates to the application without a full reload, speeding up development.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Loaders &amp;amp; Plugins:&lt;/strong&gt; An extensive ecosystem of loaders and plugins automates tasks such as transpiling, optimizing images, and more, enhancing productivity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Customizable Configuration:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Flexible Configuration:&lt;/strong&gt; Allows tailoring the build process through configuration, enabling developers to adjust settings, including specific loaders/plugins, and fine-tune optimizations as per project needs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Ecosystem and Community:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rich Ecosystem:&lt;/strong&gt; Webpack has a vibrant ecosystem with a wide range of plugins and loaders, offering solutions for various development needs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Active Community:&lt;/strong&gt; Being widely adopted, webpack has a supportive community that provides resources, tutorials, and continual updates.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Industry Standardization:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Widely Adopted:&lt;/strong&gt; It has become an industry-standard tool, with many modern web projects and frameworks integrating Webpack into their development processes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7. Optimized Production Builds:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Production-Ready Builds:&lt;/strong&gt; Webpack prepares optimized production builds, including code minification, tree shaking to remove dead code, and asset optimization.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using Webpack For Your Project
&lt;/h2&gt;

&lt;p&gt;In this section, we'll delve into the practical application of Webpack, utilizing it to power up a web project built purely with HTML, CSS, and JavaScript. By implementing Webpack, we'll illustrate firsthand how it optimizes code organization, enhances performance, and simplifies asset management.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Project Setup&lt;/strong&gt;&lt;br&gt;
First, create an empty directory and name it whatever you like, I will name mine 'Webpack-tut', after that open terminal and initialize npm, then install webpack and webpack-cli&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm init -y
npm install webpack webpack-cli --save-dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We'll begin by making a slight adjustment to our directory arrangement. This involves dividing our codebase into distinct sections: the "source" directory (./src), where our primary code is written and edited, and the "distribution" directory (./dist), which houses the optimized output of our build process. The "source" segment encompasses the code we actively work on, while the "distribution" section holds the minimized and optimized code intended for loading in the browser. This modification in our directory structure ensures a clearer organization of our project components and facilitates an efficient build process.&lt;/p&gt;

&lt;p&gt;dist/index.html&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&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;meta charset="utf-8" /&amp;gt;
    &amp;lt;title&amp;gt;Webpack Tut&amp;lt;/title&amp;gt;
   &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;script src="./src/index.js"&amp;gt;&amp;lt;/script&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now in src/index.js let's say we required to use lodash, one way is to include the lodash through HTML like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;script src="https://unpkg.com/lodash@4.17.20"&amp;gt;&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This method of managing JavaScript projects presents several challenges:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It's not instantly obvious that the script relies on an external library.&lt;/li&gt;
&lt;li&gt;Incorrect or missing dependencies can lead to dysfunctional application behavior.&lt;/li&gt;
&lt;li&gt;Including unused dependencies compels the browser to download unnecessary code, impacting performance.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So, we will use webpack to handle this.&lt;/p&gt;

&lt;p&gt;Now install lodash from terminal&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install --save lodash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;src/index.js&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import _ from 'lodash';

 function component() {
   const element = document.createElement('div');

  // Lodash, now imported by this script
   element.innerHTML = _.join(['Hello', 'webpack'], ' ');

   return element;
 }

 document.body.appendChild(component());
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this configuration, index.js makes a clear requirement for the presence of lodash, assigning it as _ without polluting the global scope. By specifying a module's dependencies, webpack utilizes this data to construct a dependency graph. This graph is then utilized to create an optimized bundle, ensuring that scripts execute in the appropriate sequence.&lt;/p&gt;

&lt;p&gt;Now remove the lodash script from the dist/index.html&lt;/p&gt;

&lt;p&gt;Also, change the js loaded to be &lt;code&gt;main.js&lt;/code&gt;, because once we run the &lt;code&gt;npx webpack&lt;/code&gt; it will generate the dist/main.js as the output, from the entry (src/index.js).&lt;/p&gt;

&lt;p&gt;Now run&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Launch the index.html file located in the dist directory using your browser. If the process is successful, you'll witness the text 'Hello webpack' displayed on the page.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Add Webpack Configuration&lt;/strong&gt;&lt;br&gt;
From version 4 onwards, webpack operates without necessitating configuration. However, for more intricate project requirements, webpack facilitates a configuration file. This approach proves more efficient than manually entering multiple commands into the terminal. Hence, let's proceed to create one.&lt;/p&gt;

&lt;p&gt;Create Webpack config file and paste this code&lt;/p&gt;

&lt;p&gt;webpack.config.js&lt;br&gt;
&lt;/p&gt;

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

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'main.js',
    path: path.resolve(__dirname, 'dist'),
  },
 mode: 'development'
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Loading CSS&lt;/strong&gt;&lt;br&gt;
In order to import a CSS file from within a JavaScript module, you need to install and add the style-loader and css-loader to your module configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install --save-dev style-loader css-loader
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And update the config file&lt;br&gt;
&lt;/p&gt;

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

 module.exports = {
   entry: './src/index.js',
   output: {
     filename: 'bundle.js',
     path: path.resolve(__dirname, 'dist'),
   },
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: ['style-loader', 'css-loader'],
      },
    ],
  },
 };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Loaders within webpack can be linked together in a chain. Each loader in this chain applies transformations to the processed resource. The chain operates in reverse order, wherein the initial loader provides its output (resource with applied transformations) to the subsequent loader, continuing in this manner. Eventually, webpack anticipates JavaScript to be returned by the ultimate loader in the chain.&lt;/p&gt;

&lt;p&gt;Maintaining the sequence of loaders is crucial: 'style-loader' should precede 'css-loader'. Deviating from this sequence might lead to webpack encountering errors.&lt;/p&gt;

&lt;p&gt;Add &lt;code&gt;style.css&lt;/code&gt; under the &lt;code&gt;src/&lt;/code&gt; directory, and now you can import it from your js files, like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import './style.css';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run &lt;code&gt;npx run webpack&lt;/code&gt; and open the &lt;code&gt;dist/index.html&lt;/code&gt; file, in the browser look at the html content from inspect, and yohoo! you see the CSS file bing imprted by webpack during the build&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Loading Images&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Add this into your module rule in the config file&lt;br&gt;
webpack.config.js&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;     {
        test: /\.(png|svg|jpg|jpeg|gif)$/i,
        type: 'asset/resource',
      },
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can import images like this in your js files&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import MyImage from './webpack.jpg'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and again run the command to build your app again&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Using Watch Mode&lt;/strong&gt;&lt;br&gt;
Running the build command every time is an annoying process, you can add a watch command from your package.json file so anytime you change something this command will run for you instead of running &lt;code&gt;npx run webpack&lt;/code&gt;, now add this into your scripts in package.json&lt;br&gt;
package.json&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    "watch": "webpack --watch",
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a comprehensive understanding and to leverage webpack's full potential, it's highly recommended to delve into its official documentation. Exploring the documentation unveils a vast array of possibilities, additional features, advanced configurations, and best practices that can further enhance your web development projects. Embracing the documentation is key to harnessing the complete power of webpack and customizing it to suit specific project needs, making your development journey more efficient and rewarding.&lt;/p&gt;

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

&lt;p&gt;In conclusion, webpack stands as an indispensable tool in modern web development, revolutionizing the way developers manage, organize, and optimize their projects. Its ability to efficiently bundle modules, optimize assets, and streamline development workflows has made it a cornerstone in building robust, performant web applications.&lt;/p&gt;

&lt;p&gt;By providing a sophisticated ecosystem of loaders, plugins, and a configurable setup, webpack empowers developers to create leaner, faster, and more maintainable codebases. The seamless integration of webpack into projects ensures improved performance, reduced load times, and a more structured approach to managing dependencies.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>webpack</category>
      <category>buildtools</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Building Stunning Docs: Diving Deep into Docusaurus Customization</title>
      <dc:creator>Joseph01</dc:creator>
      <pubDate>Sun, 19 Nov 2023 11:56:40 +0000</pubDate>
      <link>https://forem.com/joseph42a/building-stunning-docs-diving-deep-into-docusaurus-customization-33jp</link>
      <guid>https://forem.com/joseph42a/building-stunning-docs-diving-deep-into-docusaurus-customization-33jp</guid>
      <description>&lt;p&gt;In the realm of web development, documentation stands as a cornerstone for successful projects. Enter Docusaurus—a streamlined, open-source documentation framework designed to simplify the creation of elegant and intuitive documentation websites.&lt;/p&gt;

&lt;p&gt;Docusaurus offers a powerful yet straightforward approach to crafting documentation. With Markdown-based content creation and user-friendly workflows, it empowers developers to focus on content without the hassle of intricate HTML, while ensuring flexibility and ease of navigation.&lt;/p&gt;

&lt;p&gt;In this comprehensive guide, we delve into the intricacies of Docusaurus, exploring its features, setup, customization options, and advanced functionalities. Join us on this journey as we uncover the art of leveraging Docusaurus to create compelling and effective documentation sites.&lt;/p&gt;

&lt;h2&gt;
  
  
  Docusaurus
&lt;/h2&gt;

&lt;p&gt;Docusaurus functions as a static-site generator that constructs a single-page application, enabling rapid client-side navigation and harnessing React's robust capabilities to imbue your site with interactivity. While it comes equipped with pre-built documentation features, its versatility extends to the creation of diverse sites, including personal websites, products, blogs, marketing landing pages, and more.&lt;/p&gt;

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

&lt;p&gt;To create Docusaurus run the command below in your terminal, it will scaffold the new Docusaurus project with its latest version (currently v3)&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npx create-docusaurus@latest my-website classic --typescript&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
There are more templates to choose from when you create the Docusaurus app but we stick with the standard documentation, a blog, and custom pages which is a &lt;code&gt;classic&lt;/code&gt; template, and to use with typescript add the flag &lt;code&gt;--typescript&lt;/code&gt; to the end of the command.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Note/ make sure you have installed node v18 or above&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Project Structure
&lt;/h2&gt;

&lt;p&gt;After running the command you have your project structured like this,&lt;/p&gt;

&lt;p&gt;├── blog&lt;br&gt;
│   ├── 2019-05-28-hola.md&lt;br&gt;
│   ├── 2019-05-29-hello-world.md&lt;br&gt;
│   └── 2020-05-30-welcome.md&lt;br&gt;
├── docs&lt;br&gt;
│   ├── doc1.md&lt;br&gt;
│   ├── doc2.md&lt;br&gt;
│   ├── doc3.md&lt;br&gt;
│   └── mdx.md&lt;br&gt;
├── src&lt;br&gt;
│   ├── css&lt;br&gt;
│   │   └── custom.css&lt;br&gt;
│   └── pages&lt;br&gt;
│       ├── styles.module.css&lt;br&gt;
│       └── index.js&lt;br&gt;
├── static&lt;br&gt;
│   └── img&lt;br&gt;
├── docusaurus.config.js&lt;br&gt;
├── package.json&lt;br&gt;
├── README.md&lt;br&gt;
├── sidebars.js&lt;br&gt;
└── yarn.lock&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;/blog/&lt;/code&gt; - This directory contains all the markdown files, of your site blogs, you can simply add a new blog by using markdown, or simply remove a blog file by deleting its file, you can combine the markdown with &lt;a href="https://mdxjs.com/" rel="noopener noreferrer"&gt;MDX&lt;/a&gt;, resulting a well-written blog post.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;/docs/&lt;/code&gt; - Just like the &lt;code&gt;blog&lt;/code&gt; directory you can create markdown files for your docs, the order of the sidebar is sequential based on your file, but you can customize the order in &lt;code&gt;sidebars.ts&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;/src/&lt;/code&gt; - Here we can add all the pages and components of our application, under the pages directory you can easily create any other pages of your website, the root is &lt;code&gt;pages/index.tsx&lt;/code&gt; add another page like &lt;code&gt;pages/showcase&lt;/code&gt; now showcase page is available under &lt;a href="http://localhost:3000/showcase" rel="noopener noreferrer"&gt;http://localhost:3000/showcase&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;/static/&lt;/code&gt; - Static directory. Any contents inside here will be copied into the root of the final &lt;code&gt;build&lt;/code&gt; directory&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;/docusaurus.config.js&lt;/code&gt; - This is the site configuration file, where you can add the metadata, navbar links, footer links, and title, etc...&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;/sidebars.js&lt;/code&gt; as we mentioned above used to specify the order of documents in the sidebar&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can run the app by running&lt;br&gt;
&lt;code&gt;npm run start&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Congratulations! You have just created your first Docusaurus site, let's see what we can do with it.&lt;/p&gt;
&lt;h2&gt;
  
  
  Docursaurus config
&lt;/h2&gt;

&lt;p&gt;The Docusaurus configuration file serves as the control center for shaping and customizing your Docusaurus-powered website. This essential file, often named docusaurus.config.js, encapsulates various settings and options that govern the behavior, appearance, and functionality of your site.&lt;/p&gt;

&lt;p&gt;Within this configuration file, developers wield the power to define crucial parameters, such as site metadata, navigation structure, theme customization, plugin integration, and more. It acts as the foundation upon which the entire website is built, allowing users to tailor and fine-tune their site to meet specific project requirements and preferences.&lt;/p&gt;

&lt;p&gt;By editing the Docusaurus configuration file, developers can seamlessly adjust the site's branding, manage navigation menus, enable or disable features, configure SEO settings, and incorporate plugins to enhance the site's capabilities. This centralized file not only simplifies the customization process but also provides a structured approach to efficiently manage and scale the website.&lt;/p&gt;

&lt;p&gt;With its comprehensive yet accessible structure, the Docusaurus configuration file empowers developers to shape their website's identity and functionality, ensuring a tailored and polished online presence aligned with their vision and objectives.&lt;/p&gt;
&lt;h2&gt;
  
  
  Override Theme Components
&lt;/h2&gt;

&lt;p&gt;One of the coolest things that I like is Overriding components from an existing theme or building your own theme from the ground up.&lt;/p&gt;

&lt;p&gt;This process is called &lt;a href="https://docusaurus.io/docs/swizzling" rel="noopener noreferrer"&gt;Component Swizzling&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;[Swizzling] comes from Objective-C and Swift-UI: method swizzling is the process of changing the implementation of an existing selector (method). For Docusaurus, component swizzling means providing an alternative component that takes precedence over the component provided by the theme.&lt;/p&gt;

&lt;p&gt;What does this mean in practice? for example, you want to have a different footer rather than using a config file to add footer items, so for that, you can create a &lt;code&gt;/theme&lt;/code&gt; directory under the &lt;code&gt;/src&lt;/code&gt; directory, and create &lt;code&gt;/Footer/index.tsx&lt;/code&gt; now Docusaurus will no longer use its default &lt;code&gt;Footer&lt;/code&gt; that comes from the classic template.&lt;/p&gt;

&lt;p&gt;But there is one step left we have to run a command to swizzle the footer away for that run the command below&lt;br&gt;
&lt;code&gt;npm run swizzle @docusaurus/theme-classic Footer -- --eject&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
By cloning the component from the Docusaurus package into our workspace, we've gained complete control over the appearance and style of the site's footer. This allows us the freedom to customize this specific element while retaining the ability to utilize other components from the theme, ensuring compatibility with future updates as well.&lt;/p&gt;
&lt;h2&gt;
  
  
  Using ThemedImage
&lt;/h2&gt;

&lt;p&gt;Docusaurus supports themed images: the ThemedImage component (included in the themes) allows you to switch the image source based on the current theme.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import ThemedImage from '@theme/ThemedImage';

&amp;lt;ThemedImage
  alt="Docusaurus themed image"
  sources={{
    light: useBaseUrl('/img/docusaurus_light.svg'),
    dark: useBaseUrl('/img/docusaurus_dark.svg'),
  }}
/&amp;gt;;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;As we conclude this journey, it's clear that Docusaurus isn't just a documentation framework; it's a catalyst for developers seeking streamlined, elegant, and effective solutions in presenting their projects. Its user-centric approach, rich features, and adaptability make it an indispensable asset in the toolkit of developers, teams, and organizations striving for excellence in their online presence.&lt;/p&gt;

</description>
      <category>docusaurus</category>
      <category>webdev</category>
      <category>frontend</category>
      <category>documentation</category>
    </item>
  </channel>
</rss>
