<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: syed kamruzzaman</title>
    <description>The latest articles on DEV Community by syed kamruzzaman (@kamruzzaman).</description>
    <link>https://dev.to/kamruzzaman</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%2F839866%2F17c0a8a4-b1c1-4933-bfed-e59ab9f68bc8.jpg</url>
      <title>DEV Community: syed kamruzzaman</title>
      <link>https://dev.to/kamruzzaman</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kamruzzaman"/>
    <language>en</language>
    <item>
      <title>Chat App Deploy on Kubernetes Using Kind, Metallb and Ingress</title>
      <dc:creator>syed kamruzzaman</dc:creator>
      <pubDate>Tue, 31 Dec 2024 20:37:18 +0000</pubDate>
      <link>https://dev.to/kamruzzaman/chat-app-deploy-on-kubernetes-using-kind-metallb-and-ingress-2e3</link>
      <guid>https://dev.to/kamruzzaman/chat-app-deploy-on-kubernetes-using-kind-metallb-and-ingress-2e3</guid>
      <description>&lt;p&gt;This guide provides step-by-step instructions for deploying a full-stack chat application on Kubernetes using Kind, Metallb, and Ingress. It is designed to help developers set up a robust Kubernetes cluster for hosting containerized applications on a virtual private server (VPS).&lt;/p&gt;

&lt;p&gt;The deployment includes setting up essential Kubernetes tools, configuring a load balancer, integrating SSL for secure communication, and deploying both the frontend and backend services. Additionally, optional sections cover monitoring the application with Prometheus and Grafana for enhanced observability and performance tracking.&lt;/p&gt;

&lt;p&gt;Whether you are deploying a chat application for production or exploring Kubernetes capabilities, this guide will serve as a comprehensive roadmap to get your application up and running efficiently.&lt;/p&gt;

&lt;h2&gt;
  
  
  🚀 Getting Started For k8s
&lt;/h2&gt;

&lt;p&gt;Below table helps you to navigate to the particular tool installation section fast.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tech stack&lt;/th&gt;
&lt;th&gt;Installation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Docker&lt;/td&gt;
&lt;td&gt;Install and configure Docker&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Kind &amp;amp; Kubectl&lt;/td&gt;
&lt;td&gt;Install and configure Kind &amp;amp; Kubectl&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Metallb&lt;/td&gt;
&lt;td&gt;Install Metallb&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ingress&lt;/td&gt;
&lt;td&gt;Install and configure Ingress&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Helm&lt;/td&gt;
&lt;td&gt;Helm Install and configure&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SSL Certificate&lt;/td&gt;
&lt;td&gt;Install and configure Cert Manager&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Project Deploy&lt;/td&gt;
&lt;td&gt;Project Deploy and Others&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Monitoring&lt;/td&gt;
&lt;td&gt;Namespace Create for Groping Prometheus and grafana and Other&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Prometheus&lt;/td&gt;
&lt;td&gt;Install and configure Prometheus&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Grafana&lt;/td&gt;
&lt;td&gt;Install and configure Grafana&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  📢 Pre-requisites to implement this project:
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;[!Note]&lt;br&gt;
vps minimum need &lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;&lt;b&gt;RAM - 4GB&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;CPU - 2 Core(s)&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Storage - 20 GB&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;One Domain&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;🐳 &lt;b id="docker"&gt;Docker Install and configure &lt;/b&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get update

&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install &lt;/span&gt;docker.io &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;usermod &lt;span class="nt"&gt;-aG&lt;/span&gt; docker &lt;span class="nv"&gt;$USER&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; newgrp docker

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;📦 &lt;b id="kind"&gt;Kind &amp;amp; Kubectl Install and configure &lt;/b&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Install KIND and kubectl using the provided script. Create kind_kubectl_config.yaml file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;

&lt;span class="c"&gt;# For AMD64 / x86_64&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;uname&lt;/span&gt; &lt;span class="nt"&gt;-m&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; x86_64 &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; curl &lt;span class="nt"&gt;-Lo&lt;/span&gt; ./kind https://kind.sigs.k8s.io/dl/v0.26.0/kind-linux-amd64
&lt;span class="nb"&gt;chmod&lt;/span&gt; +x ./kind
&lt;span class="nb"&gt;sudo cp&lt;/span&gt; ./kind /usr/local/bin/kind

&lt;span class="nv"&gt;VERSION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"v1.31.0"&lt;/span&gt;
&lt;span class="nv"&gt;URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"https://dl.k8s.io/release/&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;VERSION&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/bin/linux/amd64/kubectl"&lt;/span&gt;
&lt;span class="nv"&gt;INSTALL_DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/usr/local/bin"&lt;/span&gt;

curl &lt;span class="nt"&gt;-LO&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$URL&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nb"&gt;chmod&lt;/span&gt; +x kubectl
&lt;span class="nb"&gt;sudo mv &lt;/span&gt;kubectl &lt;span class="nv"&gt;$INSTALL_DIR&lt;/span&gt;/
kubectl version &lt;span class="nt"&gt;--client&lt;/span&gt;

&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; kubectl
&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; kind

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"kind &amp;amp; kubectl installation complete."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./kind_kubectl_config.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;[!Note]&lt;br&gt;
If your Vps ARM64 then use this &lt;strong&gt;[ $(uname -m) = x86_64 ] &amp;amp;&amp;amp; curl -Lo ./kind &lt;a href="https://kind.sigs.k8s.io/dl/v0.26.0/kind-linux-amd64" rel="noopener noreferrer"&gt;https://kind.sigs.k8s.io/dl/v0.26.0/kind-linux-amd64&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
Run this script and it cerate kubectl and kind environment.&lt;br&gt;
&lt;a href="https://kind.sigs.k8s.io/docs/user/quick-start/" rel="noopener noreferrer"&gt;Kind Install More Information&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;🛠️ Setting Up the KIND Cluster&lt;/strong&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Create a kind-cluster-config.yaml file:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4

nodes:
- role: control-plane
  image: kindest/node:v1.31.2
- role: worker
  image: kindest/node:v1.31.2
- role: worker
  image: kindest/node:v1.31.2
  extraPortMappings:
  - containerPort: 80
    hostPort: 80
    protocol: TCP
  - containerPort: 443
    hostPort: 443
    protocol: TCP
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create the cluster using the configuration file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kind create cluster --config kind-cluster-config.yaml --name my-kind-cluster
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify the cluster:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl get nodes
kubectl cluster-info
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;[!Note]&lt;br&gt;
Here i add extraPortMappings for running Ingress&lt;/p&gt;
&lt;/blockquote&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%2Fyf63x7qnwni9qg0agmfk.jpg" 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%2Fyf63x7qnwni9qg0agmfk.jpg" alt="Image description" width="800" height="131"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🍏 &lt;b id="metallb"&gt;Metallb Install &lt;/b&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;[!Note]&lt;br&gt;
I am using Metallb for use LoadBalance. Suppose you are using Aws/Azure/DigitalOcean ect whose provide kubernates loadBalance facility then doesn't need Metallb. Here I buy VPS from a local company. They give one IP address to access VPS.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.14.9/config/manifests/metallb-frr.yaml

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

&lt;/div&gt;



&lt;p&gt;Check Metallb configuration&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl get all -n metallb-system
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Ffxnzcn7lxqh67vd42nbl.jpg" 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%2Ffxnzcn7lxqh67vd42nbl.jpg" alt="Image description" width="800" height="287"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  🛠️ Create a metallb_config.yaml file:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: first-pool
  namespace: metallb-system
spec:
  addresses:
  - 160.191.163.33-160.191.163.33
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;apply metallb_config.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;kubectl apply -f metallb_config.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;[!Note]&lt;br&gt;
MY VPS IP address is 160.191.163.33. Change this IP as your require&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;♻️ &lt;b id="ingress"&gt;Ingress Install and configure&lt;/b&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl apply -f https://kind.sigs.k8s.io/examples/ingress/deploy-ingress-nginx.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fix6hgbvsnoujd7rqv9u9.jpg" 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%2Fix6hgbvsnoujd7rqv9u9.jpg" alt="Image description" width="800" height="293"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;[!Note]&lt;br&gt;
Here service/ingress-nginx-controller show  EXTERNAL-IP is your VPS IP. My VPS IP is 160.191.163.33. It ensure that Our Metallb LoadBalance wroking.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;🧊 &lt;b id="helm"&gt;Helm Install and configure&lt;/b&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
chmod 700 get_helm.sh

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

&lt;/div&gt;



&lt;p&gt;Check Helm Version&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&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%2Fc1hglvybxj4a9njbbqzq.jpg" 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%2Fc1hglvybxj4a9njbbqzq.jpg" alt="Image description" width="800" height="85"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🔒🌐 &lt;b id="ssl_certificate"&gt;Install and configure Cert Manager || SSL Certificate&lt;/b&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;helm repo add jetstack https://charts.jetstack.io --force-update
helm repo update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Installing cert-manager CRDs&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;helm install cert-manager --namespace cert-manager --version v1.16.2 jetstack/cert-manager
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://artifacthub.io/packages/helm/cert-manager/cert-manager" rel="noopener noreferrer"&gt;https://artifacthub.io/packages/helm/cert-manager/cert-manager&lt;/a&gt;&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%2F7hnggq5o8eom2b5b4c2d.jpg" 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%2F7hnggq5o8eom2b5b4c2d.jpg" alt="Image description" width="800" height="298"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;📚 &lt;b id="project"&gt;Project Deploy and Others&lt;/b&gt;&lt;/strong&gt;
&lt;/h2&gt;

&lt;h4&gt;
  
  
  Step One
&lt;/h4&gt;

&lt;p&gt;Clone the below Project in your VPS&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone https://github.com/kamruzzamanripon/k8-node-react-mongodb-app.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Step Two
&lt;/h4&gt;

&lt;p&gt;Go to k8s folder and you can see this file \&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%2Fjv3abtdsol9yds6p3wr1.jpg" 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%2Fjv3abtdsol9yds6p3wr1.jpg" alt="Image description" width="270" height="743"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Step Three
&lt;/h4&gt;

&lt;p&gt;Create Nampe Space&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl apply -f namespace.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Step Four
&lt;/h4&gt;

&lt;p&gt;Apply all Secret file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl apply -f backend-secret.yaml
kubectl apply -f jwt-secret.yaml
kubectl apply -f mongodb-secret.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Step Five
&lt;/h4&gt;

&lt;p&gt;Declear Mongodb Volumes and Others&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl apply -f mongo-pv.yaml
kubectl apply -f mongo-pvc.yaml
kubectl apply -f mongodb-deployment.yaml
kubectl apply -f mongodb-service.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Step Six
&lt;/h4&gt;

&lt;p&gt;Apply the Rest of Other file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl apply -f backend-deployment.yaml
kubectl apply -f backend-service.yaml
kubectl apply -f frontend-deployment.yaml
kubectl apply -f frontend-service.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Step Seven
&lt;/h4&gt;

&lt;p&gt;Configure SSL Certificate Domain. Open ssl_certificate.yaml and edit your desired domain name &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%2Fhvmvo8xkftdparbnnkc4.jpg" 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%2Fhvmvo8xkftdparbnnkc4.jpg" alt="Image description" width="800" height="747"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Apply ssl_certificate.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;kubectl apply -f ssl_certificate.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Step Eight
&lt;/h4&gt;

&lt;p&gt;Configure  Ingress file.  Open ingress.yaml and add your desired domain name. \&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%2Fxq4gl7ak8f5pcx84fvbs.jpg" 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%2Fxq4gl7ak8f5pcx84fvbs.jpg" alt="Image description" width="602" height="859"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Apply ingress.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;kubectl apply -f ingress.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Check Certificate
&lt;/h3&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%2Fz0lwmsfyj2v5nk0p7z7q.jpg" 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%2Fz0lwmsfyj2v5nk0p7z7q.jpg" alt="Image description" width="800" height="146"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Check NameSpace
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl get all -n chat-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2F9fwszlphjpa3gcqdxzgp.jpg" 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%2F9fwszlphjpa3gcqdxzgp.jpg" alt="Image description" width="800" height="315"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🌐 Browser View
&lt;/h2&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%2Fk5hc30r6bvxeva3mrnvm.jpg" 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%2Fk5hc30r6bvxeva3mrnvm.jpg" alt="Image description" width="800" height="430"&gt;&lt;/a&gt;&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%2F6xllollq1mbcylrn6px5.jpg" 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%2F6xllollq1mbcylrn6px5.jpg" alt="Image description" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Congratulations! You’ve successfully deployed the &lt;strong&gt;Full-Stack Chat Application&lt;/strong&gt; . You can now access your Chat App. &lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;💻 &lt;b id="monitor"&gt;Monitoring and Others [Optional]&lt;/b&gt;&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Now we are doing Extra features like Monitoring. It helps you learn about servers and apps.&lt;/p&gt;

&lt;h4&gt;
  
  
  Create Namespace
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl create namespace monitoring
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check Namespace&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%2Fs23gw2jg4ij05mkdrdyt.jpg" 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%2Fs23gw2jg4ij05mkdrdyt.jpg" alt="Image description" width="800" height="231"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;[!Note]&lt;br&gt;
This Namespace helping to control all monitoring app like- Prometheus, Grafana, Loki ect&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  &lt;b id="prometheus"&gt;Prometheus and Grafana Install and Configure&lt;/b&gt;
&lt;/h2&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; helm install prometheus-stack prometheus-community/kube-prometheus-stack --namespace monitoring --set prometheus.service.nodePort=30000 --set grafana.service.nodePort=31000 --set grafana.service.type=NodePort --set prometheus.service.type=NodePort
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Run Prometheus Via Port
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; kubectl port-forward svc/prometheus-stack-kube-prom-prometheus 9090:9090 -n monitoring --address=0.0.0.0 &amp;amp;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;now you can access Prometheus using this port. Like&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://160.191.163.33:9090
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;[!Note]&lt;br&gt;
Change IP Address&lt;/p&gt;
&lt;/blockquote&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%2Frj54bs7wnkfiee5h2vyq.jpg" 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%2Frj54bs7wnkfiee5h2vyq.jpg" alt="Image description" width="800" height="419"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;b id="grafana"&gt;Grafana Install and Configure&lt;/b&gt;&lt;/strong&gt;&lt;br&gt;
Run Grafana Via Port&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl port-forward svc/prometheus-stack-grafana 3000:80 -n monitoring --address=0.0.0.0  &amp;amp;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Get Grafana Username and Password
&lt;/h4&gt;

&lt;p&gt;UserName&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;password&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl get secret prometheus-stack-grafana -n monitoring -o jsonpath="{.data.admin-password}" | base64 --decode
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fkrpsjzw50ow04cu2k643.jpg" 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%2Fkrpsjzw50ow04cu2k643.jpg" alt="Image description" width="800" height="419"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;[!Note]&lt;br&gt;
You can change password&lt;/p&gt;
&lt;/blockquote&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%2Fib3z7po90fj8xttkpn1v.jpg" 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%2Fib3z7po90fj8xttkpn1v.jpg" alt="Image description" width="800" height="412"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Grafana Dashboard.
&lt;/h4&gt;

&lt;p&gt;Here you can choose different type Algorithm Dashboard &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%2Fialltop1i9pflxqjzp95.jpg" 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%2Fialltop1i9pflxqjzp95.jpg" alt="Image description" width="800" height="417"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That’s all. Happy Learning :) .&lt;br&gt;
[if it is helpful, giving a star to the repository 😇]&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Project Github Link&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://github.com/kamruzzamanripon/k8-node-react-mongodb-app" rel="noopener noreferrer"&gt;https://github.com/kamruzzamanripon/k8-node-react-mongodb-app&lt;/a&gt;&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>javascript</category>
      <category>node</category>
      <category>devops</category>
    </item>
    <item>
      <title>লাইভ ডেলিভারি পিজা অ্যাপ</title>
      <dc:creator>syed kamruzzaman</dc:creator>
      <pubDate>Sun, 06 Oct 2024 13:49:07 +0000</pubDate>
      <link>https://dev.to/kamruzzaman/laaibh-ddelibhaari-pijaa-ayaap-57a3</link>
      <guid>https://dev.to/kamruzzaman/laaibh-ddelibhaari-pijaa-ayaap-57a3</guid>
      <description>&lt;p&gt;ছোট একটি Laravel CRUD প্রজেক্ট। এই প্রজেক্ট-এ Service pattern Apply করা হয়েছে। তবে এই প্রজেক্ট এর মূল ফিচার হল Advance ফিচার। এগুলো হলো –&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Event Feature.&lt;/li&gt;
&lt;li&gt;Real Time Notification System.&lt;/li&gt;
&lt;li&gt;Database Notification System.&lt;/li&gt;
&lt;li&gt;Mail Feature.&lt;/li&gt;
&lt;li&gt;Database Backup Feature.&lt;/li&gt;
&lt;li&gt;Schedule command Feature.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;বর্তমানে competition  অনেক বেশি। আপনার পোটফোলিওতে যদি এইসব Advance Feature সহ একটি  Project থাকে তাহলে আপনি কিছুটা হলেও  এগিয়ে থাকবেন। &lt;br&gt;
আর সর্বশেষে কিভাবে VPS Server এ Deploy করবো, তা দেখানো চেষ্টা করবো।&lt;br&gt;
আশা করি আপনাদের ভাল লাগবে।&lt;/p&gt;

&lt;p&gt;&lt;a href="https://youtu.be/JBnB-deqlUc" rel="noopener noreferrer"&gt;Project Introduction&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  PlayList
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/playlist?list=PLxRrj38qyjLA-cpzBuHCdACx0Y-wTRc3E" rel="noopener noreferrer"&gt;Project PlayList&lt;/a&gt;&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>react</category>
      <category>reverb</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Dockerizing a Laravel App: Nginx, MySql, PhpMyAdmin, and Php-8.2</title>
      <dc:creator>syed kamruzzaman</dc:creator>
      <pubDate>Mon, 08 Jul 2024 18:13:47 +0000</pubDate>
      <link>https://dev.to/kamruzzaman/dockerizing-a-laravel-app-nginx-mysql-phpmyadmin-and-php-82-43ne</link>
      <guid>https://dev.to/kamruzzaman/dockerizing-a-laravel-app-nginx-mysql-phpmyadmin-and-php-82-43ne</guid>
      <description>&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%2Fp2ki2ogjgj76toy14afi.jpg" 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%2Fp2ki2ogjgj76toy14afi.jpg" alt="Image description" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is Docker?&lt;/strong&gt;&lt;br&gt;
Docker is an open-source platform that enables developers to automate the deployment, scaling, and management of applications using containerization. Containers package an application and its dependencies into a single, lightweight unit that runs consistently across different computing environments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why Do We Need Docker?&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Consistency Across Environments: Docker ensures that your application runs the same way regardless of where it’s deployed — whether on a developer’s local machine, a testing server, or in production. This eliminates the “it works on my machine” problem.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Isolation: Containers encapsulate everything needed to run an application, ensuring that dependencies, libraries, and configurations are isolated from other applications. This isolation prevents conflicts between different applications on the same host.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Scalability: Docker makes it easy to scale applications horizontally by running multiple container instances. This can be managed dynamically based on load and demand, leading to better resource utilization and performance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Efficiency: Containers are lightweight and share the host system’s kernel, making them more efficient than traditional virtual machines (VMs) which include a full operating system.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Rapid Deployment: Docker containers can be quickly created, started, stopped, and destroyed. This rapid provisioning accelerates development, testing, and deployment cycles.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Portability: Containers can run on any system that supports Docker, providing great flexibility in deployment choices, whether on-premises or in the cloud.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;### Prerequisite Laravel App Setup with Docker&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Install Docker&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For Windows: Download and install Docker Desktop from the &lt;a href="https://docs.docker.com/build-cloud/" rel="noopener noreferrer"&gt;Docker website&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;For macOS: Download and install Docker Desktop from the &lt;a href="https://docs.docker.com/build-cloud/" rel="noopener noreferrer"&gt;Docker website&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;For Linux: Follow the instructions on the &lt;a href="https://docs.docker.com/build-cloud/" rel="noopener noreferrer"&gt;Docker website&lt;/a&gt; for your specific Linux distribution.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ensure Docker is running by executing the following command in your terminal:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Install Docker Compose&lt;/strong&gt;&lt;br&gt;
Docker Compose is a tool for defining and running multi-container Docker applications. It’s often used for setting up complex environments with multiple services (like web servers, databases, etc.).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For Windows and macOS: Docker Compose is included with Docker Desktop.&lt;/li&gt;
&lt;li&gt;For Linux: Install Docker Compose following the instructions on the Docker Compose installation page.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Verify the installation 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;docker-compose –version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;### Set Up a Laravel Project&lt;/strong&gt;&lt;br&gt;
If you don’t have a Laravel project already, you can create a new one. If you already have a Laravel project, skip this step.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;composer create-project laravel/laravel example-app
cd example-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;### Dockerize Laravel application&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;1. Create a Dockerfile in your root project&lt;/strong&gt;&lt;br&gt;
A Dockerfile is a script that contains instructions on how to build a Docker image for your application.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM php:8.2-fpm-alpine

ARG user
ARG uid

RUN apk update &amp;amp;&amp;amp; apk add \
    curl \
    libpng-dev \
    libxml2-dev \
    zip \
    unzip \
    shadow  # Add shadow package to install useradd

RUN docker-php-ext-install pdo pdo_mysql \
    &amp;amp;&amp;amp; apk --no-cache add nodejs npm

COPY --from=composer:latest /usr/bin/composer /usr/local/bin/composer

#USER root

#RUN chmod 777 -R /var/www/

RUN useradd -G www-data,root -u $uid -d /home/$user $user
RUN mkdir -p /home/$user/.composer &amp;amp;&amp;amp; \
    chown -R $user:$user /home/$user
WORKDIR /var/www
USER $user
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we pass two Arguments one is user and the other is uid for create a new user and other permission.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Create a docker-compose folder. And inside this folder create the below folder&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mysql&lt;/li&gt;
&lt;li&gt;Nginx&lt;/li&gt;
&lt;li&gt;- ssl&lt;/li&gt;
&lt;li&gt;Php&lt;/li&gt;
&lt;li&gt;Redis&lt;/li&gt;
&lt;li&gt; - data
&lt;strong&gt;Like this way&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6ebj1heqr4jeoun68mdd.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%2F6ebj1heqr4jeoun68mdd.png" alt="Image description" width="467" height="450"&gt;&lt;/a&gt;&lt;br&gt;
Here are other files we will create later.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Create a docker-compose.yml file in your root project&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;docker-compose.yml&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

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

services:

####################################################################################################
# app
####################################################################################################
  app:
    build:
      args:
        user: developer
        uid: 1000
      context: ./
      dockerfile: Dockerfile
    image: app
    container_name: app-rifive-laravel
    restart: unless-stopped
    environment:
      VIRTUAL_HOST: laravel.test
    working_dir: /var/www/
    volumes:
      - ./:/var/www
      - ~/.ssh:/root/.ssh
    depends_on:
      - db
      - redis  
    networks:
      - laravel

####################################################################################################
# DATABASE (MySQL)
####################################################################################################
  db:
    image: mysql:8.0
    container_name: mysql-rifive-laravel
    restart: unless-stopped
    ports:
      - "3306:3306"
    environment:
      MYSQL_DATABASE: ${DB_DATABASE}
      MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
      MYSQL_PASSWORD: ${DB_PASSWORD}
      MYSQL_USER: ${DB_USERNAME}
      SERVICE_TAGS: dev
      SERVICE_NAME: mysql
    volumes:
      - ./docker-compose/mysql/data:/var/lib/mysql
      - ./docker-compose/mysql/logs:/var/log/mysql
      - ./docker-compose/mysql/ql:/docker-entrypoint-initdb.d
    networks:
      - laravel
####################################################################################################
# Nginx
####################################################################################################      
  nginx:
    image: nginx:alpine
    container_name: nginx-rifive-laravel
    restart: unless-stopped
    ports:
      - 80:80
      - 443:443
    volumes:
      - ./:/var/www
      - ./docker-compose/nginx:/etc/nginx/conf.d
      - ./docker-compose/nginx/ssl:/etc/nginx/conf.d/ssl
      - ./docker-compose/nginx/phpmyadmin.conf:/etc/nginx/conf.d/phpmyadmin.conf
    networks:
      - laravel

####################################################################################################
# phpMyAdmin
####################################################################################################      
  phpmyadmin:
    image: phpmyadmin/phpmyadmin:latest
    container_name: phpmyadmin-rifive-laravel
    ports:
        - 8080:80
    links:
        - db
    restart: unless-stopped
    environment:
        PMA_HOST: db
        #PMA_USER: ${DB_USERNAME}
        #PMA_PASSWORD: ${DB_PASSWORD}
        PMA_PORT: 3306
        PMA_ARBITRARY: 1
    networks:
        - laravel

 ####################################################################################################
# Redis
####################################################################################################
  redis:
    image: "redis:alpine"
    container_name: ri-rifive-redis
    restart: unless-stopped
    volumes:
        - ./docker-compose/redis/data:/data
    ports:
      - "6379:6379"
    networks:
      - laravel      
networks:
  laravel:
    driver: bridge
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;here we create 5 image&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Laravel App&lt;/li&gt;
&lt;li&gt;Database MySQL&lt;/li&gt;
&lt;li&gt;Nginx&lt;/li&gt;
&lt;li&gt;PhpMyAdmin&lt;/li&gt;
&lt;li&gt;Redis&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;4. Create a Necessary file for nginx. Go to docker-compose/nginx Folder and create these files&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;laravel.conf&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;server {
    listen 80;
    server_name laravel.test;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    server_name laravel.test;
    index index.php index.html;

    error_log  /var/log/nginx/error.log;
    access_log /var/log/nginx/access.log;
    root /var/www/public;

    ssl_certificate /etc/nginx/conf.d/ssl/self-signed.crt;
    ssl_certificate_key /etc/nginx/conf.d/ssl/self-signed.key;

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass app:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }

    location / {
        try_files $uri $uri/ /index.php?$query_string;
        gzip_static on;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;phpMyAdmin.conf&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;server {
    listen 80;
    server_name phpmyadmin.laravel.test;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    server_name phpmyadmin.laravel.test;
    index index.php index.html;

    error_log  /var/log/nginx/error.log;
    access_log /var/log/nginx/access.log;
    root /usr/share/nginx/html;

    ssl_certificate /etc/nginx/conf.d/ssl/self-signed.crt;
    ssl_certificate_key /etc/nginx/conf.d/ssl/self-signed.key;

    location / {
        proxy_pass http://phpmyadmin:80;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;**&lt;/p&gt;

&lt;h2&gt;
  
  
  ::::Now run docker Container::::
&lt;/h2&gt;

&lt;p&gt;**&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 up –build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;when build is complete then run this command&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker compose exec -it app sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Favy5lxagev7rgm5lk185.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%2Favy5lxagev7rgm5lk185.png" alt="Image description" width="720" height="129"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now you can see your shell terminal. If you run whoami command then you see developer as a user. Run below 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;cd docker-compose/nginx/ssl/
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout self-signed.key -out self-signed.crt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command creates two files in your docker-compose/nginx/ssl folder.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;self-signed.crt&lt;/li&gt;
&lt;li&gt;self-signed.key
Like this picture&lt;/li&gt;
&lt;/ol&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%2Foat0vo09jy79g2ngn7nc.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%2Foat0vo09jy79g2ngn7nc.png" alt="Image description" width="720" height="416"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now run 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;cd /var/www
php artisan migrate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;now you exit shell command and your application will be ready for run. Hit this URL&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Laravel App&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://localhost
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;PhpMyAdmin&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://localhost:8080/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s all. Happy Learning :) .&lt;br&gt;
[if it is helpful, giving a star to the repository 😇]&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kamruzzamanripon/docker-laravel-nginx" rel="noopener noreferrer"&gt;https://github.com/kamruzzamanripon/docker-laravel-nginx&lt;/a&gt;&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>nginx</category>
      <category>mysql</category>
      <category>phpmyadmin</category>
    </item>
    <item>
      <title>Laravel Vue SPA Admin Panel with Taildwindcss</title>
      <dc:creator>syed kamruzzaman</dc:creator>
      <pubDate>Sun, 14 Jan 2024 09:50:58 +0000</pubDate>
      <link>https://dev.to/kamruzzaman/laravel-vue-spa-admin-panel-with-taildwindcss-2eem</link>
      <guid>https://dev.to/kamruzzaman/laravel-vue-spa-admin-panel-with-taildwindcss-2eem</guid>
      <description>&lt;p&gt;Sometimes we work on an app That’s time, we need a simple Admin Panel. But most of the Admin Panel has a lot of components and features. But we need a simple Admin Panel for custom modification as design and logic demand. Today I discuss this simple SPA admin panel.&lt;/p&gt;

&lt;p&gt;Below you can see the short video about this project -&lt;/p&gt;

&lt;p&gt;&lt;a href="https://youtu.be/chKGnSIX5rc" rel="noopener noreferrer"&gt;Project Overview&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step-1&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Install Laravel latest app&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;composer create-project laravel/laravel spa-admin-panel
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step-2&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Install necessary packages.&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 vue
npm install vue-router
npm install pinia
npm install  @vitejs/plugin-vue
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step-3&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Install Tailwindcss and setup Tailwindcss 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;npx tailwindcss init -p
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open tailwind.config.js and do this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/** @type {import('tailwindcss').Config} */
export default {
  content: [
    "./resources/**/*.blade.php",
    "./resources/**/*.js",
    "./resources/**/*.vue",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then go to resources folder then css folder and open app.css and write this code-&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Now you finished your tailwindcss setup&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step-4&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Vite configure setup. Open your vite.config.js and do 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 vue from '@vitejs/plugin-vue';
import laravel from 'laravel-vite-plugin';
import { defineConfig } from 'vite';

export default defineConfig({
    plugins: [
        laravel({
            input: ['resources/css/app.css', 'resources/js/app.js'],
            refresh: true,
        }),
        vue(),
    ],
    resolve: {
        alias: {
            vue: 'vue/dist/vue.esm-bundler.js',
        },
    },
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then open welcome.blade.php and do 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;!DOCTYPE html&amp;gt;
&amp;lt;html lang="{{ str_replace('_', '-', app()-&amp;gt;getLocale()) }}"&amp;gt;
    &amp;lt;head&amp;gt;
        &amp;lt;meta charset="utf-8"&amp;gt;
        &amp;lt;meta name="viewport" content="width=device-width, initial-scale=1"&amp;gt;

        &amp;lt;title&amp;gt;Laravel&amp;lt;/title&amp;gt;

        &amp;lt;!-- Fonts --&amp;gt;
        &amp;lt;link rel="preconnect" href="https://fonts.bunny.net"&amp;gt;
        &amp;lt;link href="https://fonts.bunny.net/css?family=figtree:400,600&amp;amp;display=swap" rel="stylesheet" /&amp;gt;

        @vite(['resources/js/app.js', 'resources/css/app.css'])
    &amp;lt;/head&amp;gt;
    &amp;lt;body &amp;gt;
        &amp;lt;div id="app"&amp;gt;
            &amp;lt;app-component&amp;gt;&amp;lt;/app-component&amp;gt;
        &amp;lt;/div&amp;gt;
    &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step-5&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;App-component defined on app.js. Go to resources / js folder and open app.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 { createPinia } from 'pinia';
import { createApp } from "vue";
import './bootstrap';

//Component import
import AppComponent from './App.vue';
import router from "./routes/index.js";

//define 
const app = createApp({});
const pinia = createPinia()

//define as component
app.component("app-component", AppComponent);

//use package 
app.use(pinia)
app.use(router)

app.mount("#app");
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we configure vue, pinia, vue-router and then define app-component.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step-6&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Make some folders and App.vue file inside js folder below 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%2F0bucl22xigrnlea37e7i.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%2F0bucl22xigrnlea37e7i.png" alt="Image description" width="563" height="1294"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step-7&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Configure router file. Go to resources / js / routes and create index.js file. Write this code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { createRouter, createWebHistory } from "vue-router";
import AuthLayout from "../components/layouts/AuthLayout.vue";
import DefaultLayout from "../components/layouts/DefaultLayout.vue";
import Page404 from "../views/PageNotFound.vue";
import About from "../views/about/About.vue";
import Login from "../views/auth/Login.vue";
import Register from "../views/auth/Register.vue";
import Dashboard from "../views/dashboard/Dashboard.vue";

const routes = [
    {
        path: "/",
        redirect: "/dashboard",
        component: DefaultLayout,
        children: [
           { path: "/dashboard", name: "Dashboard", component: Dashboard,  meta: { title: "Dashboard" } },
           { path: '/about', name: "About", component: About },
        ],
    },
    {
        path: "/auth",
        redirect: "/login",
        name: "Auth",
        component: AuthLayout,
        children: [
            { path: "/login", name: "Login", component: Login },
            { path: "/register", name: "Register", component: Register },

        ],
    },
    {
        path: "/:pathMatch(.*)*",
        name: "NotFound",
        component: Page404,
    },
];


const router = createRouter( {
    history: createWebHistory(),
    routes,
} );

// Update the document title on each route change
router.beforeEach((to, from, next) =&amp;gt; {
    document.title = to.meta.title || 'Kamruzzaman';
    next();
  });

export default router;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step-8&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Make layout component.&lt;br&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%2Favitbgdxw13cnslzrvnk.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%2Favitbgdxw13cnslzrvnk.png" alt="Image description" width="581" height="1295"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AuthLayout.vue&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;template&amp;gt;
    &amp;lt;section class="flex flex-col h-screen"&amp;gt;
        &amp;lt;!-- navbar --&amp;gt;
        &amp;lt;nav class="w-full py-4 bg-blue-600 px-3 min-h-[10%] flex justify-center"&amp;gt;
           &amp;lt;img src="../../assets/coffeeLogo.png" alt="coffeeLogo" class="h-11"&amp;gt;
        &amp;lt;/nav&amp;gt;

        &amp;lt;router-view /&amp;gt;

        &amp;lt;!-- footer --&amp;gt;
        &amp;lt;footer class="w-full py-3 bg-blue-800 text-center text-white min-h-[5%]"&amp;gt;
            This is coypright@syed kamruzzaman, just fun 😂
        &amp;lt;/footer&amp;gt;

    &amp;lt;/section&amp;gt;
&amp;lt;/template&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;DefaultLayout.vue&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;template&amp;gt;
    &amp;lt;div class="relative min-h-screen"&amp;gt;
        &amp;lt;Sidebar /&amp;gt;
        &amp;lt;!-- navbar --&amp;gt;
        &amp;lt;div
            class="bg-gray-700 py-4 px-4 text-light-grey flex justify-between items-center fixed left-0 right-0 z-10"
        &amp;gt;
            &amp;lt;ToggleIcon
                class="my-1 w-6 h-6 sm:w-7 sm:h-7 text-gray-100 bg-dark-blue cursor-pointer md:hidden"
                @click="toggleSidebar"
            /&amp;gt;
            &amp;lt;div class="cursor-pointer"&amp;gt;
                &amp;lt;router-link :to="{ name: 'Dashboard' }"&amp;gt;
                    &amp;lt;img
                        src="../../assets/coffeeLogo.png"
                        class="h-8"
                    /&amp;gt;
                &amp;lt;/router-link&amp;gt;
            &amp;lt;/div&amp;gt;
            &amp;lt;div class="flex gap-4"&amp;gt;

                &amp;lt;div class="flex items-center gap-4"&amp;gt;
                    &amp;lt;h1
                        class="cursor-pointer font-renner_medium text-white"
                        title="Representative"
                    &amp;gt;
                        Hi, Kamruzzaman 
                    &amp;lt;/h1&amp;gt;
                &amp;lt;/div&amp;gt;
                &amp;lt;div class="dropdown inline-block relative"&amp;gt;
                    &amp;lt;UserIcon class="w-9 h-9 cursor-pointer fill-white" /&amp;gt;
                    &amp;lt;ul
                        class="dropdown-menu min-w-max absolute right-0 hidden text-gray-700 pt-5"
                    &amp;gt;
                        &amp;lt;li
                            class="bg-gray-200 hover:bg-gray-400 py-2 px-4 block whitespace-no-wrap cursor-pointer"
                            @click="logout"
                        &amp;gt;
                            logout
                        &amp;lt;/li&amp;gt;
                    &amp;lt;/ul&amp;gt;
                &amp;lt;/div&amp;gt;
            &amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;!-- navbar --&amp;gt;
        &amp;lt;!-- main section --&amp;gt;
        &amp;lt;section
            class="relative pt-[70px] md:pl-[256px]"
            :class="[showSideBar ? '' : 'md:pl-[66px]']"
        &amp;gt;
            &amp;lt;router-view&amp;gt;&amp;lt;/router-view&amp;gt;
        &amp;lt;/section&amp;gt;
        &amp;lt;!-- /main section --&amp;gt;

        &amp;lt;!-- Footer Section --&amp;gt;
        &amp;lt;div class="bg-gray-700 py-4 px-4 text-light-grey flex justify-center items-center fixed left-0 right-0 bottom-0 z-10"&amp;gt;
            &amp;lt;p class="text-white mx-auto"&amp;gt;copyright@syedKamruzzamn&amp;lt;/p&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;!-- End Footer Section --&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/template&amp;gt;

&amp;lt;script setup&amp;gt;
import { computed } from 'vue';
import { basicStore } from '../../store/basicStore';
import ToggleIcon from "../icons/ToggleIcon.vue";
import UserIcon from "../icons/UserIcon.vue";
import Sidebar from "./Sidebar.vue";

const basicStoreInfo = basicStore();

const toggleSidebar =()=&amp;gt;{
    basicStoreInfo.showSideBar = !basicStoreInfo.showSideBar;
}
const logout =()=&amp;gt;{
    alert("hello Ripon");
}

const showSideBar = computed(() =&amp;gt; basicStoreInfo.showSideBar)

&amp;lt;/script&amp;gt;

&amp;lt;style scoped&amp;gt;
.dropdown:hover .dropdown-menu {
    display: block;
}

&amp;lt;/style&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Sidebar.vue&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;template&amp;gt;
    &amp;lt;!-- desktop sidebar  --&amp;gt;
    &amp;lt;div
        class="bg-gray-300 text-light-grey h-screen hidden w-full md:block md:fixed md:top-0 md:bottom-0 md:z-10 md:pt-[68px]"
        :class="[showSideBar ? 'md:w-64' : 'md:w-16']"
    &amp;gt;
        &amp;lt;ChevronLeftIcon
            class="relative -right-48 ml-5 my-2 w-8 h-8 stroke-2 text-light-grey bg-dark-blue cursor-pointer"
            v-if="showSideBar"
            @click="toggleSidebar"
        /&amp;gt;
        &amp;lt;ChevronRightIcon
            class="ml-5 my-2 w-8 h-8 stroke-2 text-light-grey bg-dark-blue cursor-pointer"
            v-if="!showSideBar"
            @click="toggleSidebar"
        /&amp;gt;

        &amp;lt;nav class="relative"&amp;gt;

            &amp;lt;SidebarItem
                to="Dashboard"
                class="group relative"
                :class="{
                    ['router-link-active router-link-exact-active']:
                        $route.path.match('dashboard') !== null,
                }"
            &amp;gt;
                &amp;lt;CompanyIcon class="w-10 h-10 fill-white" /&amp;gt;
                &amp;lt;span class="group-hover:opacity-100 transition-opacity bg-gray-800 px-3 text-sm text-gray-100 rounded-md absolute left-1/2 -translate-x-1/2 translate-y-full opacity-0 m-4 mx-auto"
                v-if="!showSideBar"
                &amp;gt;Dashboard&amp;lt;/span&amp;gt;
                &amp;lt;span
                    class="sidebar-item text-white"
                    :class="[showSideBar ? 'block' : 'hidden']"
                    &amp;gt;Dashboard&amp;lt;/span
                &amp;gt;
            &amp;lt;/SidebarItem&amp;gt;


            &amp;lt;SidebarItem
                to="About"
                class="group relative"
                :class="{
                    ['router-link-active router-link-exact-active']:
                        $route.path.match('about') !== null,
                }"
            &amp;gt;
                &amp;lt;OrdersIcon class="w-6 h-10 fill-white ml-2" /&amp;gt;
                &amp;lt;span class="group-hover:opacity-100 transition-opacity bg-gray-800 px-3 text-sm text-gray-100 rounded-md absolute left-1/2 -translate-x-1/2 translate-y-full opacity-0 m-4 mx-auto"
                v-if="!showSideBar"
                &amp;gt;About&amp;lt;/span&amp;gt;
                &amp;lt;span
                    class="sidebar-item ml-2 text-white"
                    :class="[showSideBar ? 'block' : 'hidden']"
                    &amp;gt;About&amp;lt;/span
                &amp;gt;
            &amp;lt;/SidebarItem&amp;gt;

        &amp;lt;/nav&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;!-- /desktop sidebar --&amp;gt;

    &amp;lt;!-- mobile side bar --&amp;gt;
    &amp;lt;MobileSidebar /&amp;gt;
    &amp;lt;!-- /mobile side bar --&amp;gt;
&amp;lt;/template&amp;gt;

&amp;lt;script setup&amp;gt;
import ChevronLeftIcon from "../icons/ChevronLeftIcon.vue";
import ChevronRightIcon from "../icons/ChevronRightIcon.vue";
import CompanyIcon from "../icons/CompnayIcon.vue";
import OrdersIcon from "../icons/OrdersIcon.vue";
import SidebarItem from "./SidebarItem.vue";

import { computed, ref } from 'vue';
import { basicStore } from '../../store/basicStore';
import MobileSidebar from "./MobileSidebar.vue";

const basicStoreInfo = basicStore();
const show = ref(true)

const toggleSidebar =()=&amp;gt;{
    basicStoreInfo.showSideBar = !basicStoreInfo.showSideBar;
}

const showSideBar = computed(() =&amp;gt; basicStoreInfo.showSideBar)

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;SidebarItem.vue&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;template&amp;gt;
    &amp;lt;router-link
        :to="{ name: to }"
        class="flex items-center gap-2 px-3 py-2 hover:bg-light-gold transition duration-200 cursor-pointer"
    &amp;gt;
        &amp;lt;slot&amp;gt;&amp;lt;/slot&amp;gt;
    &amp;lt;/router-link&amp;gt;
&amp;lt;/template&amp;gt;

&amp;lt;script&amp;gt;
export default {
    props: {
        to: {
            required: true,
            type: String,
            default: "Dashboard",
        },
    },
    computed: {
        routeName() {
            return this.$route.name;
        },
    },
};
&amp;lt;/script&amp;gt;

&amp;lt;style scoped&amp;gt;
.router-link-active,
.router-link-exact-active {
    background: #4c4c54;
}
&amp;lt;/style&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;MobileSidebar.vue&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;template&amp;gt;
    &amp;lt;!-- mobile side bar --&amp;gt;
    &amp;lt;div
        class="fixed bg-gray-600 h-screen w-full z-10 md:hidden  transition-all duration-500 ease-in-out"
        :class="[showSideBar ? '-top-[1px] sm:70px block' : '-top-[900px]']"
    &amp;gt;
        &amp;lt;nav class="mt-[80px]"&amp;gt;
            &amp;lt;SidebarItem
                to="Dashboard"
                :class="{
                    ['router-link-active router-link-exact-active']:
                        $route.path.match('dashboard') !== null,
                }"
                @click="toggleSidebar"
            &amp;gt;
                &amp;lt;CompanyIcon class="w-10 h-10 fill-white text-light-grey" /&amp;gt;
                &amp;lt;span class="sidebar-item text-gray-100"&amp;gt;Dashboard &amp;lt;/span&amp;gt;
            &amp;lt;/SidebarItem&amp;gt;

            &amp;lt;SidebarItem
                to="About"
                :class="{
                    ['router-link-active router-link-exact-active']:
                        $route.path.match('about') !== null,
                }"
                @click="toggleSidebar"
            &amp;gt;
                &amp;lt;CompanyIcon class="w-10 h-10 fill-white text-light-grey" /&amp;gt;
                &amp;lt;span class="sidebar-item text-gray-100"&amp;gt;About &amp;lt;/span&amp;gt;
            &amp;lt;/SidebarItem&amp;gt;


        &amp;lt;/nav&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;!-- /mobile side bar --&amp;gt;
&amp;lt;/template&amp;gt;

&amp;lt;script setup&amp;gt;
import { computed } from 'vue';
import { basicStore } from '../../store/basicStore';
import CompanyIcon from "../icons/CompnayIcon.vue";
import SidebarItem from "./SidebarItem.vue";

const basicStoreInfo = basicStore();

const toggleSidebar =()=&amp;gt;{
    basicStoreInfo.showSideBar = !basicStoreInfo.showSideBar;
}

const showSideBar = computed(() =&amp;gt; basicStoreInfo.showSideBar)

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step-9&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now we make some pages.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Dashboard&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;About&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Login&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Register&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;PageNotFound&lt;/p&gt;&lt;/li&gt;
&lt;/ol&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%2Fqhk1d1wjuvcl74vz4x1r.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%2Fqhk1d1wjuvcl74vz4x1r.png" alt="Image description" width="556" height="1350"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dashboard.vue&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;template&amp;gt;
    &amp;lt;div class="px-5 py-5"&amp;gt;
        &amp;lt;h1 class="text-3xl mb-3"&amp;gt;Dashboard Page &amp;lt;/h1&amp;gt;
        &amp;lt;p&amp;gt;
            Lorem ipsum dolor sit, amet consectetur adipisicing elit. Iure nihil nam labore deleniti ratione eius consectetur vel illo nemo reiciendis ullam, incidunt quam doloribus praesentium id, corrupti rem. Ullam dolores, non voluptate quis maxime ducimus temporibus repudiandae nihil quasi? Similique.
        &amp;lt;/p&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/template&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Desktop View and Menu Unextended&lt;br&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%2Fn4n31mep9g11odmqi5r8.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%2Fn4n31mep9g11odmqi5r8.png" alt="Desktop View and Menu Unextended" width="720" height="345"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Desktop View and Menu Extended&lt;br&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%2Fpbhtfc4jthv1qpywbg72.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%2Fpbhtfc4jthv1qpywbg72.png" alt="Image description" width="720" height="345"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Mobile View and Menu Unextended&lt;br&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%2Fw77m76zm6qsf6z4ntjbq.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%2Fw77m76zm6qsf6z4ntjbq.png" alt="Image description" width="425" height="832"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Mobile View and Menu Extended&lt;br&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%2Fn8jj2nh7kj1esi65igqa.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%2Fn8jj2nh7kj1esi65igqa.png" alt="Image description" width="426" height="830"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;About.vue&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;template&amp;gt;
    &amp;lt;div class="px-5 py-5"&amp;gt;
        &amp;lt;h1 class="text-3xl mb-3"&amp;gt;About Page&amp;lt;/h1&amp;gt;
        &amp;lt;p&amp;gt;
            Lorem ipsum dolor sit, amet consectetur adipisicing elit. Iure nihil nam labore deleniti ratione eius consectetur vel illo nemo reiciendis ullam, incidunt quam doloribus praesentium id, corrupti rem. Ullam dolores, non voluptate quis maxime ducimus temporibus repudiandae nihil quasi? Similique, accusamus eos sunt fugit tempora sit necessitatibus vero placeat corrupti voluptatem pariatur aliquid debitis corporis iusto. Suscipit, sunt!.
        &amp;lt;/p&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/template&amp;gt;

&amp;lt;script setup&amp;gt;

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

&lt;/div&gt;



&lt;p&gt;Design Look Similar Dashboard.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Login.vue&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;template&amp;gt;
    &amp;lt;div class="min-h-[85%] flex items-center justify-center bg-gray-100"&amp;gt;
      &amp;lt;div class="bg-white p-8 rounded shadow-md"&amp;gt;
        &amp;lt;h1 class="text-2xl font-semibold mb-6"&amp;gt;Login Page&amp;lt;/h1&amp;gt;

        &amp;lt;!-- Form --&amp;gt;
        &amp;lt;form @submit.prevent="login"&amp;gt;
          &amp;lt;!-- Username Input --&amp;gt;
          &amp;lt;div class="mb-4"&amp;gt;
            &amp;lt;label for="username" class="block text-gray-600 text-sm font-medium mb-2"&amp;gt;Username:&amp;lt;/label&amp;gt;
            &amp;lt;input
              type="text"
              id="username"
              v-model="username"
              class="w-full px-3 py-2 border border-gray-300 rounded focus:outline-none focus:border-blue-500"
              required
            /&amp;gt;
          &amp;lt;/div&amp;gt;

          &amp;lt;!-- Password Input --&amp;gt;
          &amp;lt;div class="mb-6"&amp;gt;
            &amp;lt;label for="password" class="block text-gray-600 text-sm font-medium mb-2"&amp;gt;Password:&amp;lt;/label&amp;gt;
            &amp;lt;input
              type="password"
              id="password"
              v-model="password"
              class="w-full px-3 py-2 border border-gray-300 rounded focus:outline-none focus:border-blue-500"
              required
            /&amp;gt;
          &amp;lt;/div&amp;gt;

          &amp;lt;!-- Submit Button --&amp;gt;
          &amp;lt;button
            type="submit"
            class="w-full bg-blue-500 text-white p-2 rounded hover:bg-blue-600 focus:outline-none focus:shadow-outline-blue"
          &amp;gt;
            Login
          &amp;lt;/button&amp;gt;
        &amp;lt;/form&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/template&amp;gt;

  &amp;lt;script&amp;gt;
  export default {
    data() {
      return {
        username: '',
        password: '',
      };
    },
    methods: {
      login() {
        // Handle login logic here
        console.log('Logging in...');
      },
    },
  };
  &amp;lt;/script&amp;gt;

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

&lt;/div&gt;



&lt;p&gt;Desktop View and Menu Unextended&lt;br&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%2Fo9wxe7rq6arna3dkify0.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%2Fo9wxe7rq6arna3dkify0.png" alt="Image description" width="720" height="345"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Desktop View and Menu Extended&lt;br&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%2Fwm25jmq6179dtx6yfbbc.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%2Fwm25jmq6179dtx6yfbbc.png" alt="Image description" width="425" height="832"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Register.vue&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;template&amp;gt;
    &amp;lt;div class="min-h-[85%] flex items-center justify-center bg-gray-100"&amp;gt;
      &amp;lt;div class="bg-white p-8 rounded shadow-md"&amp;gt;
        &amp;lt;h1 class="text-2xl font-semibold mb-6"&amp;gt;Register Page&amp;lt;/h1&amp;gt;

        &amp;lt;!-- Form --&amp;gt;
        &amp;lt;form @submit.prevent="register"&amp;gt;
          &amp;lt;!-- Username Input --&amp;gt;
          &amp;lt;div class="mb-4"&amp;gt;
            &amp;lt;label for="username" class="block text-gray-600 text-sm font-medium mb-2"&amp;gt;Username:&amp;lt;/label&amp;gt;
            &amp;lt;input
              type="text"
              id="username"
              v-model="username"
              class="w-full px-3 py-2 border border-gray-300 rounded focus:outline-none focus:border-blue-500"
              required
            /&amp;gt;
          &amp;lt;/div&amp;gt;

          &amp;lt;!-- Email Input --&amp;gt;
          &amp;lt;div class="mb-4"&amp;gt;
            &amp;lt;label for="email" class="block text-gray-600 text-sm font-medium mb-2"&amp;gt;Email:&amp;lt;/label&amp;gt;
            &amp;lt;input
              type="email"
              id="email"
              v-model="email"
              class="w-full px-3 py-2 border border-gray-300 rounded focus:outline-none focus:border-blue-500"
              required
            /&amp;gt;
          &amp;lt;/div&amp;gt;

          &amp;lt;!-- Password Input --&amp;gt;
          &amp;lt;div class="mb-6"&amp;gt;
            &amp;lt;label for="password" class="block text-gray-600 text-sm font-medium mb-2"&amp;gt;Password:&amp;lt;/label&amp;gt;
            &amp;lt;input
              type="password"
              id="password"
              v-model="password"
              class="w-full px-3 py-2 border border-gray-300 rounded focus:outline-none focus:border-blue-500"
              required
            /&amp;gt;
          &amp;lt;/div&amp;gt;

          &amp;lt;!-- Confirm Password Input --&amp;gt;
          &amp;lt;div class="mb-6"&amp;gt;
            &amp;lt;label for="confirmPassword" class="block text-gray-600 text-sm font-medium mb-2"&amp;gt;Confirm Password:&amp;lt;/label&amp;gt;
            &amp;lt;input
              type="password"
              id="confirmPassword"
              v-model="confirmPassword"
              class="w-full px-3 py-2 border border-gray-300 rounded focus:outline-none focus:border-blue-500"
              required
            /&amp;gt;
          &amp;lt;/div&amp;gt;

          &amp;lt;!-- Submit Button --&amp;gt;
          &amp;lt;button
            type="submit"
            class="w-full bg-blue-500 text-white p-2 rounded hover:bg-blue-600 focus:outline-none focus:shadow-outline-blue"
          &amp;gt;
            Register
          &amp;lt;/button&amp;gt;
        &amp;lt;/form&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/template&amp;gt;

  &amp;lt;script&amp;gt;
  export default {
    data() {
      return {
        username: '',
        email: '',
        password: '',
        confirmPassword: '',
      };
    },
    methods: {
      register() {
        // Handle registration logic here
        console.log('Registering...');
      },
    },
  };
  &amp;lt;/script&amp;gt;

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

&lt;/div&gt;



&lt;p&gt;Desktop View and Menu Unextended&lt;br&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%2Fdwarh6xjw9kjhcrud9rw.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%2Fdwarh6xjw9kjhcrud9rw.png" alt="Image description" width="720" height="345"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Desktop View and Menu Extended&lt;br&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%2Fw15j790xrh2zebnl74jn.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%2Fw15j790xrh2zebnl74jn.png" alt="Image description" width="425" height="832"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PageNotFound.vue&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;template&amp;gt;
    &amp;lt;div class="min-h-screen flex items-center justify-center bg-gray-100"&amp;gt;
      &amp;lt;div class="text-center"&amp;gt;
        &amp;lt;h1 class="text-4xl font-bold mb-6"&amp;gt;404 Not Found&amp;lt;/h1&amp;gt;
        &amp;lt;p class="text-gray-600 text-lg mb-8"&amp;gt;The page you are looking for does not exist.&amp;lt;/p&amp;gt;
        &amp;lt;router-link to="/" class="text-blue-500 hover:underline"&amp;gt;Go back to the home page&amp;lt;/router-link&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/template&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2F8x66gu2ka5vgnwbq5drz.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%2F8x66gu2ka5vgnwbq5drz.png" alt="Image description" width="720" height="345"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we have done all the necessary things. we will now configure our main route. Go to routes folder and open web.php file and do this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Route::get('/{any}', function () {
    return view('welcome');
})-&amp;gt;where("any", ".*");
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we finished our full SPA app processing.&lt;/p&gt;

&lt;p&gt;Full Project GitHub&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kamruzzamanripon/laravel-vue-pinia-admin-panel-boilerplate" rel="noopener noreferrer"&gt;https://github.com/kamruzzamanripon/laravel-vue-pinia-admin-panel-boilerplate&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That’s all. Happy Learning :) .&lt;br&gt;
[if it is helpful, giving a star to the repository 😇]&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>vue</category>
      <category>tailwindcss</category>
      <category>vite</category>
    </item>
    <item>
      <title>Deploy A NextJs App and Node API on a Linux Server</title>
      <dc:creator>syed kamruzzaman</dc:creator>
      <pubDate>Sun, 17 Dec 2023 19:49:05 +0000</pubDate>
      <link>https://dev.to/kamruzzaman/deploy-a-nextjs-app-and-node-api-on-a-linux-server-3ge8</link>
      <guid>https://dev.to/kamruzzaman/deploy-a-nextjs-app-and-node-api-on-a-linux-server-3ge8</guid>
      <description>&lt;p&gt;In this tutorial, we will learn how to deploy a NextJS app and Node Api on a Linux server. NexJS will serve as the frontend view and Node as the backend. We have already discussed Node API and NextJS app in previous articles, which you can find here:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Making API Using Node and Express. &lt;a href="https://dev.tourl"&gt;Link&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Scaffolding redux-toolkit in NextJs. &lt;a href="https://dev.tourl"&gt;Link&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;API Setup in NextJs. &lt;a href="https://dev.tourl"&gt;Link&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;AI Prompt setup on Nextjs. &lt;a href="https://dev.toURL"&gt;Link&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Linux is a popular and widely used server operating system. In this tutorial, we will be using Ubuntu 22.04.3. I assume you are familiar with Linux, so let's get started.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites Before we begin, ensure you have the following:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;one remote server (VPS)&lt;/li&gt;
&lt;li&gt;one domain &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Step 1:&lt;/strong&gt; &lt;br&gt;
Check your VPS for the following software and versions. Install them if they are not already present.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;nginx -v&lt;/li&gt;
&lt;li&gt;node -v&lt;/li&gt;
&lt;li&gt;npm&lt;/li&gt;
&lt;li&gt;mongod --version &lt;/li&gt;
&lt;li&gt;git --version&lt;/li&gt;
&lt;li&gt;pm2 –version&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Connect Your Domain to Your Server&lt;/strong&gt;&lt;br&gt;
Go to your domain manager, then to the DNS Manager, and set up your IP address. First, create a sub-domain for the Node API.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkwbl4cbbsbkg6riewh0g.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%2Fkwbl4cbbsbkg6riewh0g.png" alt="Image description" width="800" height="420"&gt;&lt;/a&gt;&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%2Fjm45iz90911r6h31hzkm.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%2Fjm45iz90911r6h31hzkm.png" alt="Image description" width="800" height="481"&gt;&lt;/a&gt;&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%2Faii8jc2txsxhjq2wl1xx.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%2Faii8jc2txsxhjq2wl1xx.png" alt="Image description" width="800" height="388"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Note: Your domain setup page may look different from this.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Then, check your DNS here: &lt;a href="https://dnschecker.org/" rel="noopener noreferrer"&gt;https://dnschecker.org/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3:&lt;/strong&gt; &lt;br&gt;
Upload Your Node and Next App to GitHub&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Server SSH Configuration&lt;/strong&gt;&lt;br&gt;
Go to your server and check if there is an .ssh folder. If not, create one:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Now create a key for your Node app:&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 -f node_movie_api -t ed25519 -C "your_email@example.com"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should now see two files in your .ssh folder:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;node_movie_api &lt;/li&gt;
&lt;li&gt;node_movie_api.pub&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Open &lt;strong&gt;node_movie_api.pub&lt;/strong&gt; and copy the code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cat node_movie_api.pub
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, go to your GitHub and open your Node project. Click the "Settings" button and paste the key in the key field.&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%2Fgn9nlwsmziedx2ml46uv.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%2Fgn9nlwsmziedx2ml46uv.png" alt="Image description" width="800" height="395"&gt;&lt;/a&gt;&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%2Fi7uw18iewkveidvhzb2f.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%2Fi7uw18iewkveidvhzb2f.png" alt="Image description" width="800" height="396"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Back on your server, create a 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;touch ~/.ssh/config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and add the following code to 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;Host node_movie_api
        HostName github.com
        User your_github_username
        IdentityFile ~/.ssh/node_movie_api
        IdentitiesOnly yes

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

&lt;/div&gt;



&lt;p&gt;Check if your GitHub project connection is okay:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssh -T git@node_movie_api
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you see a message indicating successful authentication, the connection is okay.&lt;br&gt;
Now, go to your home directory and copy the GitHub link.&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%2Fephtw7t3u8wb3dx12hgr.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%2Fephtw7t3u8wb3dx12hgr.png" alt="Image description" width="800" height="1042"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Modify this link as shown below-&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone git@node_movie_api: kamruzzamanripon/node-movie-api.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;here node_movie_api is your host name. you already defined in .ssh folder inside config file. And after you just copy this thing and paste it here. &lt;br&gt;
After successfully cloning, move the cloned project to the /var/www folder.&lt;br&gt;
Then go to &lt;strong&gt;/var/www/ node-movie-api&lt;/strong&gt; folder. Then run 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;npm install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;then create this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nano ecosystem.config.cjs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module.exports = {
  apps : [
      {
        name: "nove_movie_api",
        script: "./app.js",
        port: 8000
      }
  ]
}

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 5: Create Table on MongoDB&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mongosh
show dbs
use node_movie_api

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

&lt;/div&gt;



&lt;p&gt;now you create node_movie_api table. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 6: Configure Nginx for node&lt;/strong&gt;&lt;br&gt;
Go to the Nginx folder and create a configuration file for your node app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd /etc/nginx/sites-available
sudo nano node_movie_api

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

&lt;/div&gt;



&lt;p&gt;Add the following configuration&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_domain www.your_domain;
    location / {
       proxy_pass http://localhost:8000;
       proxy_http_version 1.1;
       proxy_set_header Upgrade $http_upgrade;
       proxy_set_header Connection 'upgrade';
       proxy_set_header Host $host;
       proxy_cache_bypass $http_upgrade;
    }
}

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

&lt;/div&gt;



&lt;p&gt;Enable the virtual host or create a symbolic link of the virtual host file:&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/node_movie_api /etc/nginx/sites-enabled/node_movie_api
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check if the configuration is correct:&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;Restart 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 service nginx restart
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;*&lt;em&gt;Step 8: env file variable define *&lt;/em&gt;&lt;br&gt;
Go to /var/www/ node-movie-api or your project folder . open your .env file and change 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%2Foh10ve7of8fmrzrrabw4.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%2Foh10ve7of8fmrzrrabw4.png" alt="Image description" width="800" height="297"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 7 : make folder for image&lt;/strong&gt;&lt;br&gt;
In your public folder creates uploads folder then inside create two folder&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;category &lt;/li&gt;
&lt;li&gt;image&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;then  run &lt;strong&gt;ecosystem.config.cjs&lt;/strong&gt; file below 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;pm2 start ecosystem.config.cjs
pm2 save

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 8: Check Your Sub-Domain&lt;/strong&gt;&lt;br&gt;
Open your browser and check if your sub-domain is working without errors.&lt;br&gt;
We have successfully deployed Node app.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 9: Set Up Next App&lt;/strong&gt;&lt;br&gt;
Go to your domain manager, then to the DNS Manager, and set up your IP address for the NextJS app. Use this app on your main domain.&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%2Fwasnlwjk43zxftnez1gv.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%2Fwasnlwjk43zxftnez1gv.png" alt="Image description" width="800" height="577"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then check your DNS here: &lt;a href="https://dnschecker.org/" rel="noopener noreferrer"&gt;https://dnschecker.org/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 10: Server SSH Configuration for Nuxt App&lt;/strong&gt;&lt;br&gt;
Repeat the SSH key generation and GitHub configuration steps as done for the node app, but this time for your NextJS app. Remember to replace the relevant names and paths.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sh-keygen -f next_movie -t ed25519 -C "your_email@example.com" 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;now you can see two file in your .ssh folder&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;next_movie&lt;/li&gt;
&lt;li&gt;next_movie.pub
Now open &lt;strong&gt;next_movie.pub&lt;/strong&gt; file and copy the code.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cat next_movie.pub
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then go to your github and open your Next project. Click Settings button&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%2Fbvxky6zyj3qk37clqeuw.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%2Fbvxky6zyj3qk37clqeuw.png" alt="Image description" width="800" height="391"&gt;&lt;/a&gt;&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%2Fc8h9jrhwiojrc6jmkh5j.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%2Fc8h9jrhwiojrc6jmkh5j.png" alt="Image description" width="800" height="391"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And past his copy code on  Add deploy key&lt;br&gt;
Go to your server and open 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;Sudo nano ~/.ssh/config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and add this code into 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;Host node_movie_api
        HostName github.com
        User kamruzzamanripon
        IdentityFile ~/.ssh/ node_movie_api
        IdentitiesOnly yes

Host next_movie
        HostName github.com
        User kamruzzamanripon
        IdentityFile ~/.ssh/next_movie
        IdentitiesOnly yes

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

&lt;/div&gt;



&lt;p&gt;Now check your github project connection is ok. Here is code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssh -T git@next_movie
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now go to your Server home directory and copy github link&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%2Fwchln4kfctks0tan7q2n.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%2Fwchln4kfctks0tan7q2n.png" alt="Image description" width="800" height="902"&gt;&lt;/a&gt;&lt;br&gt;
here next_movie is your host name. you already defined in .ssh folder inside config file. And after : you just copy this thing and past here.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone git@next_movie:kamruzzamanripon/next-movie-ui-with-node-api.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your server clones this project. Now you move this file to your &lt;strong&gt;/var/www&lt;/strong&gt; folder&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Sudo mv next-movie-ui-with-node-api /var/www
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Go to www/folder. And then go nuxt-movie-ui-with-laravel-api folder. Open you next.config.js&lt;br&gt;
sudo nano next.config.js and change 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%2Fh3td5tjlmdy4pk0kozxl.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%2Fh3td5tjlmdy4pk0kozxl.png" alt="Image description" width="800" height="310"&gt;&lt;/a&gt;&lt;br&gt;
Here mark 1 is your image url. And then open your .env.local file and put you AI Api key. 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%2Fdk2o85ckihvg9z2y8s1q.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%2Fdk2o85ckihvg9z2y8s1q.png" alt="Image description" width="800" height="246"&gt;&lt;/a&gt;&lt;br&gt;
After Command below line&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
npm run build
sudo nano ecosystem.config.js

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

&lt;/div&gt;



&lt;p&gt;Write below code in &lt;strong&gt;ecosystem.config.js&lt;/strong&gt; file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module.exports = {
  apps : [
      {
        name: "next_movie",
        script: ".output/server/index.mjs",
        port: 3000
      }
  ]
}

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Restart Nginx:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Start the app using pm2:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pm2 start ecosystem.config.js
pm2 save
pm2 status

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 11: Configure Nginx for Next App&lt;/strong&gt;&lt;br&gt;
Go to the Nginx folder and create a configuration file for your Next app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd /etc/nginx/sites-available
sudo nano next_movie

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

&lt;/div&gt;



&lt;p&gt;Add the following configuration:&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_domain www.your_domain;
    location / {
       proxy_pass http://localhost:3000;
       proxy_http_version 1.1;
       proxy_set_header Upgrade $http_upgrade;
       proxy_set_header Connection 'upgrade';
       proxy_set_header Host $host;
       proxy_cache_bypass $http_upgrade;
    }

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

&lt;/div&gt;



&lt;p&gt;Enable the virtual host or create a symbolic link of the virtual host file:&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/next_movie /etc/nginx/sites-enabled/next_movie
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check if the configuration is correct:&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;Restart 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 service nginx restart
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 12: Check Your Domain&lt;/strong&gt;&lt;br&gt;
Open your browser and check if your domain is working without errors.&lt;br&gt;
Now we successfully deploy NextJs app.&lt;/p&gt;

&lt;p&gt;Remark on Git Cloning:&lt;br&gt;
It's important to note that we used SSH for git cloning instead of HTTPS. This choice is strategic for ease of future development. Imagine you've made some changes to your project locally. With SSH, all you need to do to update your project on the server is a simple git push from your local machine, followed by a git pull on the server. This process updates your app with the latest changes. Using HTTPS wouldn't offer this straightforward workflow, as it would require repeating the entire process from the beginning for every update.&lt;br&gt;
Furthermore, you can streamline the process even more by implementing auto-deployment. With this setup, any update you push to GitHub automatically reflects on your server. This automation can be achieved through GitHub Actions. In a subsequent tutorial, I plan to delve into the features of GitHub Actions and how you can use them for auto-deployment.&lt;br&gt;
Stay tuned for that, and in the meantime, enjoy the benefits of easy project updates with SSH!&lt;/p&gt;

&lt;p&gt;full Project github&lt;br&gt;
Node&lt;br&gt;
&lt;a href="https://github.com/kamruzzamanripon/node-movie-api" rel="noopener noreferrer"&gt;https://github.com/kamruzzamanripon/node-movie-api&lt;/a&gt;&lt;br&gt;
NextJs&lt;br&gt;
&lt;a href="https://github.com/kamruzzamanripon/next-movie-ui-with-node-api" rel="noopener noreferrer"&gt;https://github.com/kamruzzamanripon/next-movie-ui-with-node-api&lt;/a&gt;&lt;br&gt;
NextJs UI&lt;br&gt;
&lt;a href="https://github.com/kamruzzamanripon/next-movie-ui" rel="noopener noreferrer"&gt;https://github.com/kamruzzamanripon/next-movie-ui&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's all. Happy Learning :) .&lt;br&gt;
[if it is helpful, giving a star to the repository 😇]&lt;/p&gt;

</description>
      <category>ubuntu</category>
      <category>mern</category>
      <category>nextjs</category>
      <category>node</category>
    </item>
    <item>
      <title>AI Prompt setup on Nextjs.</title>
      <dc:creator>syed kamruzzaman</dc:creator>
      <pubDate>Sun, 17 Dec 2023 19:46:31 +0000</pubDate>
      <link>https://dev.to/kamruzzaman/ai-prompt-setup-on-nextjs-2109</link>
      <guid>https://dev.to/kamruzzaman/ai-prompt-setup-on-nextjs-2109</guid>
      <description>&lt;p&gt;In this tutorial, we have setup our AI Prompt. Previously we did 3 parts. If you don’t know then see this link&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Making API Using Node and Express. &lt;a href="https://dev.tourl"&gt;Link&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Scaffolding redux-toolkit in NextJs. &lt;a href="https://dev.tourl"&gt;Link&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;API Setup in NextJs. &lt;a href="https://dev.toURL"&gt;Link&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now we are doing 4th part. Let’s derive on-&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step-1 : .env file Setup and necessary package install&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In your root project create .env.local file and do 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%2Fb4hvmol2iitcax91a4te.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%2Fb4hvmol2iitcax91a4te.png" alt="Image description" width="800" height="284"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here API key is a AI key which you get form your Ai Dashboard.  &lt;a href="https://platform.openai.com/" rel="noopener noreferrer"&gt;https://platform.openai.com/&lt;/a&gt;&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%2Fscd4wyt40i5aamgt1a3f.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%2Fscd4wyt40i5aamgt1a3f.png" alt="Image description" width="800" height="511"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you don’t have any AI API key then crate one and put in you .env.local file. And then install this package&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  npm i openai@3.3.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step-2 : movie Api Setup&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Previously we did a movie Api setup. &lt;a href="https://dev.to/kamruzzaman/api-setup-in-nextjs-3gen"&gt;API Setup in NextJs&lt;/a&gt;.&lt;br&gt;
Go to reduxStore/features/movie folder and create this file&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;movieApi.js&lt;/li&gt;
&lt;li&gt;movieSlice.js&lt;/li&gt;
&lt;/ol&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%2Fyq1f5xpteo5wv86sj1yf.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%2Fyq1f5xpteo5wv86sj1yf.png" alt="Image description" width="483" height="455"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;movieApi.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { apiSlice } from "../api/apiSlice";

export const moviesApi = apiSlice.injectEndpoints({
    endpoints: (builder) =&amp;gt; ({
        topMovies: builder.query({
            query: () =&amp;gt;
                `/top-movies`,
        }),
        manualMovieStore: builder.mutation({
            query: (data) =&amp;gt; ({
                url: "/movie-store",
                method: "POST",
                body: data,
            }),
        }),

        aiMovieStore: builder.mutation({

            query: (data) =&amp;gt; ({

                url: "/ai-movie-store",
                method: "POST",
                body: data,

            }),
            async onQueryStarted(arg, { queryFulfilled, dispatch }) {
               console.log('redux', arg)
            },
        }),

    }),
});

export const { useTopMoviesQuery, useManualMovieStoreMutation, useAiMovieStoreMutation} = moviesApi;

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

&lt;/div&gt;



&lt;p&gt;Here we have Three end points. There are&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;"/top-movies"&lt;/li&gt;
&lt;li&gt;"/movie-store"&lt;/li&gt;
&lt;li&gt;"/ai-movie-store"&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;movieSlice.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { createSlice } from "@reduxjs/toolkit";

const initialState = {
    topMovies: [],
    aiMovieData:{},
    sampleData:"sdfsf sdfsf"

};

const movieSlice = createSlice({
    name: "movie",
    initialState,
    reducers: {
        topMovies: (state, action) =&amp;gt; {
            state.topMovies = action.payload;

        },
        aiMovieData:(state, action) =&amp;gt;{
            console.log('redux movie')
            state.aiMovieData = action.payload;
        }

    },
});

export const { topMovies, aiMovieData} = movieSlice.actions;
export default movieSlice.reducer;

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

&lt;/div&gt;



&lt;p&gt;Here we have Two actions. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;topMovies&lt;/li&gt;
&lt;li&gt;aiMovieData
Now, movieApi.js file, we have aiMovieStore method for store Ai information in our Database. Here you saw aiMovieData action method. This action store AI information in redux store.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Step-3: Ai Movie Page Setup and Others&lt;/strong&gt;&lt;br&gt;
Go to ai-make-movie folder and see page.js file. Write this code-&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import AiFormInput from "../component/ai-make-movie/AiFormInput";
import LeftSideBar from "../component/common/LeftSideBar";
import RightSideBar from "../component/common/RightSideBar";

const Page = () =&amp;gt; {
    return (
        &amp;lt;div className="flex min-h-screen"&amp;gt;
        &amp;lt;LeftSideBar /&amp;gt;
        &amp;lt;div className=" flex-1 py-10  px-5 sm:px-10 "&amp;gt;
         &amp;lt;AiFormInput /&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;RightSideBar /&amp;gt;
        &amp;lt;/div&amp;gt;
    );
};

export default Page;

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

&lt;/div&gt;



&lt;p&gt;Now go to component/ai-make-movie and you see AiFormInput.js file &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AiFormInput.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;'use client';
import { aiMovieData } from '@/app/reduxStore/features/movie/movieSlice';
import Image from 'next/image';
import { useRouter } from 'next/navigation';
import { Configuration, OpenAIApi } from 'openai';
import { useState } from "react";
import { useDispatch } from 'react-redux';
import Loading from '../../ai-make-movie/loading';

const AiFormInput = () =&amp;gt; {
  const [aiIdea, setAiIdea] = useState();
  const dispatch = useDispatch();
  const router = useRouter();
  const [loading, setLoading] = useState(false);

  //Ai configuration
  const openAiApiKey = process.env.NEXT_PUBLIC_OPEN_AI_API_KEY;
  const configuration = new Configuration({
      apiKey: openAiApiKey
  })
  const openAi = new OpenAIApi(configuration);

  //Ai form submit handle
  const handleSubmit = async (e) =&amp;gt; {
    e.preventDefault();
    setLoading(true);
    const aiSampleMovieData = await fetchSynopsis(aiIdea)
    dispatch(aiMovieData(aiSampleMovieData));
    //console.log('form submit', data)

   router.push("/movie-made")

  };

  async function fetchSynopsis(outline){
    const response = await openAi.createCompletion({
        model: 'text-davinci-003',
        prompt:`Generate an engaging, professional and marketable movie synopsis based on an outline. The synopsis should include actiors names in brackets after each character. Choose actors that would be ideal for this role.
        ###
        outline: A big-headed daredevil fighter pilot goes back to school only to be sent on a deadly mission.
        synopsis: The Top Gun Naval Fighter Weapons School is where the best of the best train to refine their elite flying skills, When hotshot fighter pilot Maverick (Tom Cruise) is sent o the school, his rackless attitude and cocky demeanor put him at odds with the other pilots, especially the cool and collected Iceman (Val kilmer). But Maverick ins't only competing to be the top fighter pilot, he's also fighting for the attention of his beautiful flight instructor, Charlotte Blackwood (kelly McGillis). Maverick gradually earns the respect of his intructors and peers - and also the love of Charlotte, but struggles to balance his personal and professional life. As the pilots prepare for a mission against a foreign enemy, Maverick must confront his own demons and overcome the tragedies rooted deep in his past to become the best fighter pilot and return from the mission triumphant.
        ###
        outline: ${outline}
        synopsis:
        `,
        max_tokens: 700
    })
    const synopsis = response.data.choices[0].text.trim();
    console.log('fetchSynopsis', synopsis)
    const aiMovieData = fetchTitle(synopsis);
    return aiMovieData;

}

async function fetchTitle(synopsis){
    const response = await openAi.createCompletion({
        model: 'text-davinci-003',
        prompt:`Generate a catchy movie title for this synopsis: ${synopsis}`,
        max_tokens: 25,
        temperature: 0.7
    })
    const title = response.data.choices[0].text.trim();
    console.log('fetchTitle-1', synopsis)
    console.log('fetchTitle-2', title)
    const aiMovieData = fetchImagePromt(title, synopsis)
    return aiMovieData;
}

async function fetchImagePromt(title, synopsis){
    const response = await openAi.createCompletion({
    model: 'text-davinci-003',
    prompt: `Give a short description of an image which could be used to advertise a movie based on a title and synopsis.The description should be rich in visual detail but contain no names.
    ###
    title: Love's Time Warp
    synopsis: When scientist and time traveller Wendy (Emma Watson) is sent back to the 1920s to assassinate a future dictator, she never expected to fall in love with them. As wendy infiltrates the dictator's inner circle, she soon finds herself torn between her mission and her growing feelings for the leader (Brie Larson). With the help of a mysterious stranger from the future (Josh Brolin), Wendy must decide whether to carry out her mission or follow her heart. But the choices she makes in the 1920s will have far-reaching consequences that reverberate throuugh the ages.
    image description: A silhouetted figure stands in the shadows of a 1920s speakeasy, her face turned away from the camera. In the background, two people are dancing in the dim light, one wearing a flapper-style dress and the other wearing a dapper suit. A semi-transparent image of war is super-imposed over the scene.
    ###
    title: zero Earth
    synopsis: When baodyguard kob (Daniel Radcliffe) is recruited by the United Nations to save Planet Earth from the sinister Simm (John Malkovich), an alien lord with a plan to take over the world, he reluctantly accepts the challenge, With the help of this loyal sidekick, a brave and resourceful hamster named Gizmo (Gaten Matarazzo), Kob embarks on a perilous mission to destroy Simm. Along the way, he discovers a newfound courage and strength as he battles Simms's merciless forces. With the fate of the world in his hands, kob must find a way to defeat the alien lord and save the planet.
    image description: A tired and bloodied bodyguard and hamster standing a top a tall skyscraper, looking out over a vibrant cityscape, with a rainbow in the sky above them.
    ###
    title: ${title}
    synopsis: ${synopsis}
    image description:
    `,
    temperature: 0.8,
    max_tokens: 100

    })
    console.log('fetchImagePromt-1', synopsis)
    console.log('fetchImagePromt-2', title)
    const aiMovieData = fetchImageUrl(response.data.choices[0].text.trim(), synopsis, title)
    return aiMovieData;
}

async function fetchImageUrl(imagePrompt,synopsis,title){
    const response = await openAi.createImage({
        prompt: `${imagePrompt}. There should be no text in this iamge.`,
        n: 1,
        size: '256x256',
        response_format: 'b64_json'
    })
    const b64JsonImage = response.data.data[0];
    console.log('fetchImageUrl-1', synopsis)
    console.log('fetchImageUrl-2', title)
     const aiMovieData ={
        b64JsonImage,
        synopsis,
        title
    }

    return aiMovieData;
}

  if(loading){
    return &amp;lt;Loading/&amp;gt;
  }

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;form onSubmit={handleSubmit}&amp;gt;
      &amp;lt;div className="bg-gray-200 p-5 rounded-md dark:bg-black"&amp;gt;
        &amp;lt;div className="text-center mb-8 relative"&amp;gt;
          &amp;lt;h1 className="text-2xl font-bold text-gray-700 mb-3 dark:text-white"&amp;gt;
            Hello, I am here to help Make Movie
          &amp;lt;/h1&amp;gt;
          &amp;lt;p className="dark:text-white"&amp;gt;
            Please, write your idea below input box
          &amp;lt;/p&amp;gt;

          &amp;lt;Image
                src="/robot-1.webp"
                alt="Bird flying animation" 
                className="rounded-full w-48 h-48 absolute top-0 right-0"
                width={105} 
                height={105} 

            /&amp;gt;
        &amp;lt;/div&amp;gt;

        &amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;
        &amp;lt;div className="mb-6"&amp;gt;
          &amp;lt;label
            htmlFor="message"
            className="block mb-2 text-sm font-medium text-gray-900 dark:text-white"
          &amp;gt;
            Type your Idea
          &amp;lt;/label&amp;gt;
          &amp;lt;textarea
            id="message"
            rows={4}
            className="block p-2.5 w-full text-sm text-gray-900 bg-gray-50 rounded-lg border border-gray-300 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
            placeholder="Type Movie Idea..."
            onChange={(e)=&amp;gt;setAiIdea(e.target.value)}

          /&amp;gt;

        &amp;lt;/div&amp;gt;
        &amp;lt;div className="text-right"&amp;gt;
          &amp;lt;button
            type="submit"
            className="bg-black text-white p-3 rounded-md dark:border"
          &amp;gt;
            Make Movie
          &amp;lt;/button&amp;gt;
        &amp;lt;/div&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;/form&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};

export default AiFormInput;


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

&lt;/div&gt;



&lt;p&gt;Here we are implement AI Prompt. Let’s do it-&lt;br&gt;
If you hit this &lt;a href="http://localhost:3000/ai-make-movie" rel="noopener noreferrer"&gt;http://localhost:3000/ai-make-movie&lt;/a&gt; URL then you can see this page-&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%2Fu5p7s7ogws5620emz96y.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%2Fu5p7s7ogws5620emz96y.png" alt="Image description" width="800" height="437"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This page has one input field. User just type his idea and then click Make Movie button then AI generate our information. Let’s drive in our code. Here you see ** handleSubmit** method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//Ai form submit handle
  const handleSubmit = async (e) =&amp;gt; {
    e.preventDefault();
    setLoading(true);
    const aiSampleMovieData = await fetchSynopsis(aiIdea)
    dispatch(aiMovieData(aiSampleMovieData));
    //console.log('form submit', data)

   router.push("/movie-made")

  };

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

&lt;/div&gt;



&lt;p&gt;This method Tigger when we click Make Movie button. This method first call &lt;strong&gt;fetchSynopsis&lt;/strong&gt; method and passed user input idea.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;async function fetchSynopsis(outline){
    const response = await openAi.createCompletion({
        model: 'text-davinci-003',
        prompt:`Generate an engaging, professional and marketable movie synopsis based on an outline. The synopsis should include actiors names in brackets after each character. Choose actors that would be ideal for this role.
        ###
        outline: A big-headed daredevil fighter pilot goes back to school only to be sent on a deadly mission.
        synopsis: The Top Gun Naval Fighter Weapons School is where the best of the best train to refine their elite flying skills, When hotshot fighter pilot Maverick (Tom Cruise) is sent o the school, his rackless attitude and cocky demeanor put him at odds with the other pilots, especially the cool and collected Iceman (Val kilmer). But Maverick ins't only competing to be the top fighter pilot, he's also fighting for the attention of his beautiful flight instructor, Charlotte Blackwood (kelly McGillis). Maverick gradually earns the respect of his intructors and peers - and also the love of Charlotte, but struggles to balance his personal and professional life. As the pilots prepare for a mission against a foreign enemy, Maverick must confront his own demons and overcome the tragedies rooted deep in his past to become the best fighter pilot and return from the mission triumphant.
        ###
        outline: ${outline}
        synopsis:
        `,
        max_tokens: 700
    })
    const synopsis = response.data.choices[0].text.trim();
    console.log('fetchSynopsis', synopsis)
    const aiMovieData = fetchTitle(synopsis);
    return aiMovieData;

}

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

&lt;/div&gt;



&lt;p&gt;This &lt;strong&gt;fetchSynopsis&lt;/strong&gt; method has dummy result, so that AI know what I need actually. Then I passed outline which I passed as aiIdea Parameter. So this method give me some result. Then I sort this result and get my Synopsis or Description. Then I call another method &lt;strong&gt;fetchTitle&lt;/strong&gt; for get a catchy Title. Here I passed my synopsis result as a Parameter.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;async function fetchTitle(synopsis){
    const response = await openAi.createCompletion({
        model: 'text-davinci-003',
        prompt:`Generate a catchy movie title for this synopsis: ${synopsis}`,
        max_tokens: 25,
        temperature: 0.7
    })
    const title = response.data.choices[0].text.trim();
    console.log('fetchTitle-1', synopsis)
    console.log('fetchTitle-2', title)
    const aiMovieData = fetchImagePromt(title, synopsis)
    return aiMovieData;
}

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

&lt;/div&gt;



&lt;p&gt;Now this method give me Movie Title require as my synopsis. Then again I call another method &lt;strong&gt;fetchImagePromt&lt;/strong&gt; for image description. Here I passed Two parameter - title and synopsis&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;async function fetchImagePromt(title, synopsis){
    const response = await openAi.createCompletion({
    model: 'text-davinci-003',
    prompt: `Give a short description of an image which could be used to advertise a movie based on a title and synopsis.The description should be rich in visual detail but contain no names.
    ###
    title: Love's Time Warp
    synopsis: When scientist and time traveller Wendy (Emma Watson) is sent back to the 1920s to assassinate a future dictator, she never expected to fall in love with them. As wendy infiltrates the dictator's inner circle, she soon finds herself torn between her mission and her growing feelings for the leader (Brie Larson). With the help of a mysterious stranger from the future (Josh Brolin), Wendy must decide whether to carry out her mission or follow her heart. But the choices she makes in the 1920s will have far-reaching consequences that reverberate throuugh the ages.
    image description: A silhouetted figure stands in the shadows of a 1920s speakeasy, her face turned away from the camera. In the background, two people are dancing in the dim light, one wearing a flapper-style dress and the other wearing a dapper suit. A semi-transparent image of war is super-imposed over the scene.
    ###
    title: zero Earth
    synopsis: When baodyguard kob (Daniel Radcliffe) is recruited by the United Nations to save Planet Earth from the sinister Simm (John Malkovich), an alien lord with a plan to take over the world, he reluctantly accepts the challenge, With the help of this loyal sidekick, a brave and resourceful hamster named Gizmo (Gaten Matarazzo), Kob embarks on a perilous mission to destroy Simm. Along the way, he discovers a newfound courage and strength as he battles Simms's merciless forces. With the fate of the world in his hands, kob must find a way to defeat the alien lord and save the planet.
    image description: A tired and bloodied bodyguard and hamster standing a top a tall skyscraper, looking out over a vibrant cityscape, with a rainbow in the sky above them.
    ###
    title: ${title}
    synopsis: ${synopsis}
    image description:
    `,
    temperature: 0.8,
    max_tokens: 100

    })
    console.log('fetchImagePromt-1', synopsis)
    console.log('fetchImagePromt-2', title)
    const aiMovieData = fetchImageUrl(response.data.choices[0].text.trim(), synopsis, title)
    return aiMovieData;
}

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

&lt;/div&gt;



&lt;p&gt;Here inside this method, first I setup dummy result then I setup my parameter. This method give me image description as require title and synopsis. Now I get Three result&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;synopsis or Description&lt;/li&gt;
&lt;li&gt;title or Movie Title&lt;/li&gt;
&lt;li&gt;imagePrompt or Image Description.
Now we call, another method &lt;strong&gt;fetchImageUrl&lt;/strong&gt; for image create.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;async function fetchImageUrl(imagePrompt,synopsis,title){
    const response = await openAi.createImage({
        prompt: `${imagePrompt}. There should be no text in this iamge.`,
        n: 1,
        size: '256x256',
        response_format: 'b64_json'
    })
    const b64JsonImage = response.data.data[0];
    console.log('fetchImageUrl-1', synopsis)
    console.log('fetchImageUrl-2', title)
     const aiMovieData ={
        b64JsonImage,
        synopsis,
        title
    }

    return aiMovieData;
}

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

&lt;/div&gt;



&lt;p&gt;This method give me Base64 image and size 256 x 256. We can increase size. Now we get three information from AI and return this information like as  object to &lt;strong&gt;handleSubmit&lt;/strong&gt; method&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//Ai form submit handle
  const handleSubmit = async (e) =&amp;gt; {
    e.preventDefault();
    setLoading(true);
    const aiSampleMovieData = await fetchSynopsis(aiIdea)
    dispatch(aiMovieData(aiSampleMovieData));
    //console.log('form submit', data)

   router.push("/movie-made")

  };

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

&lt;/div&gt;



&lt;p&gt;Here this method got all information from AI and then dispatch this information to &lt;strong&gt;aiMovieData&lt;/strong&gt; action, which we were create &lt;strong&gt;movieSlice.js&lt;/strong&gt;&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%2Fcmxt3hgg6gszghqwfrff.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%2Fcmxt3hgg6gszghqwfrff.png" alt="Image description" width="800" height="673"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, &lt;strong&gt;aiMovieDate&lt;/strong&gt; method store AI information. &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%2Fmglqlsh72bba7g4gx1xc.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%2Fmglqlsh72bba7g4gx1xc.png" alt="Image description" width="800" height="731"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we show this information in our redux extension plugin.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step-4: Ai Result Show and Others&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Go to /movie-made folder, open &lt;strong&gt;page.js&lt;/strong&gt; and do 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 AiFormResult from "../component/ai-make-movie/AiFormResult";
import LeftSideBar from "../component/common/LeftSideBar";
import RightSideBar from "../component/common/RightSideBar";

const Page = () =&amp;gt; {
    return (
        &amp;lt;div className="flex min-h-screen"&amp;gt;
        &amp;lt;LeftSideBar /&amp;gt;
        &amp;lt;div className=" flex-1 py-10  px-5 sm:px-10 "&amp;gt;
          &amp;lt;AiFormResult /&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;RightSideBar /&amp;gt;
        &amp;lt;/div&amp;gt;
    );
};

export default Page;

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

&lt;/div&gt;



&lt;p&gt;Now go to /component/ai-make-movie folder and open &lt;strong&gt;AiFormResult.js&lt;/strong&gt; and write this-&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 { useAllCategoriesQuery } from "@/app/reduxStore/features/category/categoryApi";
import { useAiMovieStoreMutation } from "@/app/reduxStore/features/movie/moviesApi";
import Image from 'next/image';
import { useRouter } from "next/navigation";
import { useEffect, useState } from "react";
import { useSelector } from "react-redux";

const AiFormResult = () =&amp;gt; {
  const [movieData, setMovieData] = useState({
    title: '',
    category_id: '',
    description: '',
    image: null, 
  });
  const aiMovieData = useSelector((state)=&amp;gt;state.movies.aiMovieData);
  const { data, isLoading, isError } = useAllCategoriesQuery();
  const router = useRouter()
  const [aiMovieStore, { isSuccess }] = useAiMovieStoreMutation();

  //b64_json convert image src
  const getImageSource = () =&amp;gt; {
    const imageData = aiMovieData?.b64JsonImage?.b64_json || '';
    return `data:image/png;base64,${imageData}`;
  };


  //for category when category change.
  const handleChange = (e) =&amp;gt; {
    const { name, value } = e.target;
    setMovieData({ ...movieData, [name]: value });
  };

  //set ai data into movieData
  useEffect(()=&amp;gt;{
    setMovieData({
      title: aiMovieData?.title,
      description: aiMovieData?.synopsis,
      image: aiMovieData?.b64JsonImage?.b64_json,
      });
  },[aiMovieData?.b64JsonImage?.b64_json, aiMovieData?.synopsis, aiMovieData?.title])

  const handleSubmit = async (e) =&amp;gt; {
    e.preventDefault();
    if(movieData.category_id == ''){
      alert('please Select Category')
      return;
    }

      console.log('Response from server:-2', movieData);

    try {
      const formData = new FormData();
      formData.append('title', movieData.title);
      formData.append('category_id', movieData.category_id);
      formData.append('description', movieData.description);
      formData.append('image', movieData.image);
      console.log('form submit', movieData)
      const response = await aiMovieStore(formData);
      // Handle the success response
      console.log('Response from server:', [...formData]);
      // Assuming you want to reset the form after successful submission
      setMovieData({
        title: '',
        category_id: '',
        description: '',
        image: null,
      });
      router.push("/");
    } catch (error) {
      // Handle the error
      console.error('Error saving the movie:', error);
    }
  };


  return (
    &amp;lt;div className="bg-gray-200 p-5 rounded-md dark:bg-black my-10"&amp;gt;
      &amp;lt;div className="text-center mb-8"&amp;gt;
        &amp;lt;h1 className="text-2xl font-bold text-gray-700 mb-3 dark:text-white"&amp;gt;
          This is your Search Result
        &amp;lt;/h1&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;form onSubmit={handleSubmit}&amp;gt;
      &amp;lt;div className="mx-10 px-10 py-16 bg-gray-400 dark:bg-black dark:border"&amp;gt;
      &amp;lt;div className="mb-6 flex items-center justify-center"&amp;gt;

          &amp;lt;Image
                src={getImageSource()}
                alt="result-image"
                className="rounded-md border border-2 border-x-1 w-[350px]"
                name="image"
                onChange={handleChange}
                width={105} 
                height={105} 
                layout="responsive"
            /&amp;gt;
        &amp;lt;/div&amp;gt;


        &amp;lt;div className="mb-6"&amp;gt;
          &amp;lt;label
            htmlFor="large-input"
            className="block mb-2 text-sm font-medium text-gray-900 dark:text-white"
          &amp;gt;
            Movie Title
          &amp;lt;/label&amp;gt;
          &amp;lt;input
            type="text"
            id="large-input"
            className="block w-full p-4 text-gray-900 border border-gray-300 rounded-lg bg-gray-50 sm:text-md focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
            placeholder="Type your Movie Title..."
            value={aiMovieData?.title}
            name="title"
            onChange={handleChange}

          /&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;div className="mb-6"&amp;gt;
            &amp;lt;label
              htmlFor="base-input"
              className="block mb-2 text-sm font-medium text-gray-900 dark:text-white"
            &amp;gt;
              Movie Category
            &amp;lt;/label&amp;gt;
            &amp;lt;select
              id="category"
              className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
              name="category_id"
              onChange={handleChange}
            &amp;gt;
              &amp;lt;option value=""&amp;gt;Choose category&amp;lt;/option&amp;gt;
              {data &amp;amp;&amp;amp; data.data?.map((category) =&amp;gt; (
                &amp;lt;option key={category._id} value={category._id}&amp;gt;
                  {category.name}
                &amp;lt;/option&amp;gt;
              ))}
            &amp;lt;/select&amp;gt;
          &amp;lt;/div&amp;gt;
        &amp;lt;div className="mb-6"&amp;gt;
          &amp;lt;label
            htmlFor="message"
            className="block mb-2 text-sm font-medium text-gray-900 dark:text-white"
          &amp;gt;
            Movie Short Description
          &amp;lt;/label&amp;gt;
          &amp;lt;textarea
            id="message"
            rows={8}
            className="block p-2.5 w-full text-sm text-gray-900 bg-gray-50 rounded-lg border border-gray-300 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
            placeholder="Type Movie short description..."
            value={aiMovieData?.synopsis}
            name="description"
            onChange={handleChange}
          /&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;div className="text-right"&amp;gt;
          &amp;lt;button className="bg-black text-white p-3 rounded-md dark:border"&amp;gt;
            Save your Movie
          &amp;lt;/button&amp;gt;
        &amp;lt;/div&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;/form&amp;gt;

    &amp;lt;/div&amp;gt;
  );
};

export default AiFormResult;

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

&lt;/div&gt;



&lt;p&gt;now hit &lt;a href="http://localhost:3000/movie-made" rel="noopener noreferrer"&gt;http://localhost:3000/movie-made&lt;/a&gt; URL then you can see this page&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%2F7vfoo5aqz4h44q420i02.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%2F7vfoo5aqz4h44q420i02.png" alt="Image description" width="800" height="659"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here This page, Show AI information. If you click &lt;strong&gt;Save your Movie&lt;/strong&gt; button then it Tigger &lt;strong&gt;aiMovieStore&lt;/strong&gt;&lt;br&gt;
Method which we were define in moviesApi.js file. This method save Ai information data in our MongoDB.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { apiSlice } from "../api/apiSlice";

export const moviesApi = apiSlice.injectEndpoints({
    endpoints: (builder) =&amp;gt; ({
        topMovies: builder.query({
            query: () =&amp;gt;
                `/top-movies`,
        }),
        manualMovieStore: builder.mutation({
            query: (data) =&amp;gt; ({
                url: "/movie-store",
                method: "POST",
                body: data,
            }),
        }),

        aiMovieStore: builder.mutation({

            query: (data) =&amp;gt; ({

                url: "/ai-movie-store",
                method: "POST",
                body: data,

            }),
            async onQueryStarted(arg, { queryFulfilled, dispatch }) {
               console.log('redux', arg)
            },
        }),

    }),
});

export const { useTopMoviesQuery, useManualMovieStoreMutation, useAiMovieStoreMutation} = moviesApi;

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

&lt;/div&gt;



&lt;p&gt;Now we Finished our AI Prompt. &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%2Fxvdcypguw4nfmnjx1h6y.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%2Fxvdcypguw4nfmnjx1h6y.png" alt="Image description" width="800" height="513"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Form page&lt;/strong&gt;&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%2F9lpw5rm2081veh495ffs.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%2F9lpw5rm2081veh495ffs.png" alt="Image description" width="800" height="513"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Loading page&lt;/strong&gt;&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%2Fqzq0labohw950qwfy39l.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%2Fqzq0labohw950qwfy39l.png" alt="Image description" width="800" height="659"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Ai Information show&lt;/strong&gt;&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%2Fg10x07iustvulxkg7t4i.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%2Fg10x07iustvulxkg7t4i.png" alt="Image description" width="370" height="1350"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Home page&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Next we deploy this App. Here is this Tutorial-&lt;/p&gt;

&lt;p&gt;Deploy A NextJs App and Node API on a Linux Server. &lt;a href="https://dev.to/kamruzzaman/deploy-a-nextjs-app-and-node-api-on-a-linux-server-3ge8"&gt;Link&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;full Project github&lt;br&gt;
Node&lt;br&gt;
&lt;a href="https://github.com/kamruzzamanripon/node-movie-api" rel="noopener noreferrer"&gt;https://github.com/kamruzzamanripon/node-movie-api&lt;/a&gt;&lt;br&gt;
NextJs&lt;br&gt;
&lt;a href="https://github.com/kamruzzamanripon/next-movie-ui-with-node-api" rel="noopener noreferrer"&gt;https://github.com/kamruzzamanripon/next-movie-ui-with-node-api&lt;/a&gt;&lt;br&gt;
NextJs UI&lt;br&gt;
&lt;a href="https://github.com/kamruzzamanripon/next-movie-ui" rel="noopener noreferrer"&gt;https://github.com/kamruzzamanripon/next-movie-ui&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's all. Happy Learning :) .&lt;br&gt;
[if it is helpful, giving a star to the repository 😇]&lt;/p&gt;

</description>
      <category>ai</category>
      <category>node</category>
      <category>nextjs</category>
      <category>javascript</category>
    </item>
    <item>
      <title>API Setup in NextJs</title>
      <dc:creator>syed kamruzzaman</dc:creator>
      <pubDate>Sun, 17 Dec 2023 19:44:12 +0000</pubDate>
      <link>https://dev.to/kamruzzaman/api-setup-in-nextjs-3gen</link>
      <guid>https://dev.to/kamruzzaman/api-setup-in-nextjs-3gen</guid>
      <description>&lt;p&gt;In this tutorial we have integrate other Api. Previously we did 1st part and 2nd part. If you don’t know then see this link&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Making API Using Node and Express. &lt;a href="https://dev.toURL"&gt;Link&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Scaffolding redux-toolkit in NextJs. &lt;a href="https://dev.toURL"&gt;Link&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now we are do 3rd part. Let’s derive on-&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step-1 : Authentication Api Setup&lt;/strong&gt;&lt;br&gt;
Go to reduxStore/features/auth folder and create this file&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;authApi.js&lt;/li&gt;
&lt;li&gt;authSlice.js&lt;/li&gt;
&lt;/ol&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%2Fa56o6mqaj4sassn3nyee.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%2Fa56o6mqaj4sassn3nyee.png" alt="Image description" width="508" height="469"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;authApi.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { apiSlice } from "../api/apiSlice";
import { userLoggedIn } from "./authSlice";

export const authApi = apiSlice.injectEndpoints({
    endpoints: (builder) =&amp;gt; ({
        register: builder.mutation({
            query: (data) =&amp;gt; ({
                url: "/register",
                method: "POST",
                body: data,
            }),
            async onQueryStarted(arg, { queryFulfilled, dispatch }) {
                try {
                    const result = await queryFulfilled;

                    localStorage.setItem(
                        "auth",
                        JSON.stringify({
                            accessToken: result.data.accessToken,
                            user: result.data.user,
                        })
                    );

                    dispatch(
                        userLoggedIn({
                            accessToken: result.data.accessToken,
                            user: result.data.user,
                        })
                    );
                } catch (err) {
                    // do nothing
                }
            },
        }),
        login: builder.mutation({
            query: (data) =&amp;gt; ({
                url: "/login",
                method: "POST",
                body: data,
            }),

            async onQueryStarted(arg, { queryFulfilled, dispatch }) {
                try {
                    const result = await queryFulfilled;
                    console.log('data fetch', result)
                    localStorage.setItem(
                        "auth",
                        JSON.stringify({
                            accessToken: result.data.payload.token,
                            user:result.data.payload,
                        })
                    );

                    dispatch(
                        userLoggedIn({
                            accessToken: result.data.payload.token,
                            user: result.data.payload,
                        })
                    );
                } catch (err) {
                    // do nothing
                }
            },
        }),
    }),
});

export const { useLoginMutation, useRegisterMutation } = authApi;

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

&lt;/div&gt;



&lt;p&gt;Here this authApi we have 2 end points. &lt;br&gt;
    1. "/register" for register user &lt;br&gt;
    2. "/login" for login user.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;authSlice.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { createSlice } from "@reduxjs/toolkit";

const initialState = {
    accessToken: undefined,
    user: undefined,
};

const authSlice = createSlice({
    name: "auth",
    initialState,
    reducers: {
        userLoggedIn: (state, action) =&amp;gt; {
            state.accessToken = action.payload.accessToken;
            state.user = action.payload.user;
        },
        userLoggedOut: (state) =&amp;gt; {
            state.accessToken = undefined;
            state.user = undefined;
        },
    },
});

export const { userLoggedIn, userLoggedOut } = authSlice.actions;
export default authSlice.reducer;

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

&lt;/div&gt;



&lt;p&gt;Here this authSlice we have two actions. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;userLoggedIn &lt;/li&gt;
&lt;li&gt;userLoggedOut.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Step-2 : Login page Setup and Others&lt;/strong&gt;&lt;br&gt;
Go to login folder and create page.js file and do this&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;page.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

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

import { useRouter } from 'next/navigation';
import { useEffect, useState } from "react";
import { useLoginMutation } from "../reduxStore/features/auth/authApi";
import Error from "../component/common/Error";

const Page = () =&amp;gt; {
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const [error, setError] = useState("");

  const [login, { data, isLoading, error: responseError }] = useLoginMutation();
  const router = useRouter();
  console.log('login data', data)
  const handleSubmit = (e) =&amp;gt; {
    e.preventDefault();
    console.log("loging data", email, password)
    setError("");

    login({
      email,
      password,
    });

    router.push("/");
  };

  useEffect(() =&amp;gt; {
    if (responseError?.data) {
      setError(responseError.data);
    }
    if (data?.accessToken &amp;amp;&amp;amp; data?.user) {
      router.push("/");
    }
  }, [data, responseError, router]);

  return (
    &amp;lt;div className="flex h-screen items-center justify-center bg-gray-100"&amp;gt;
      &amp;lt;div className="bg-white p-8 shadow-md rounded-lg w-80"&amp;gt;
        &amp;lt;h1 className="text-2xl font-semibold mb-4"&amp;gt;Login &amp;lt;/h1&amp;gt;
        &amp;lt;form onSubmit={handleSubmit}&amp;gt;
          &amp;lt;div className="mb-4"&amp;gt;
            &amp;lt;label className="block text-sm font-medium text-gray-700"&amp;gt;Email&amp;lt;/label&amp;gt;
            &amp;lt;input
              type="email"
              className="mt-1 block w-full border rounded-md px-3 py-2 text-red-800"
              required
              value={email}
              onChange={(e) =&amp;gt; setEmail(e.target.value)}
            /&amp;gt;
          &amp;lt;/div&amp;gt;
          &amp;lt;div className="mb-4"&amp;gt;
            &amp;lt;label className="block text-sm font-medium text-gray-700"&amp;gt;
              Password
            &amp;lt;/label&amp;gt;
            &amp;lt;input
              type="password"
              className="mt-1 block w-full border rounded-md px-3 py-2 text-red-800"
              required
              value={password}
              onChange={(e) =&amp;gt; setPassword(e.target.value)}
            /&amp;gt;
          &amp;lt;/div&amp;gt;
          &amp;lt;button
            type="submit"
            className="bg-blue-500 text-white py-2 px-4 rounded hover:bg-blue-600"
          &amp;gt;
            Login
          &amp;lt;/button&amp;gt;
        &amp;lt;/form&amp;gt;

        {error !== "" &amp;amp;&amp;amp; &amp;lt;Error message={error} /&amp;gt;}
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};

export default Page;

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

&lt;/div&gt;



&lt;p&gt;Hit “/login” URL show the Login page. &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%2Fsfl27f1do1hxocpb7xni.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%2Fsfl27f1do1hxocpb7xni.png" alt="Image description" width="800" height="387"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now go to “/component/common/&lt;strong&gt;LeftSideBar.js&lt;/strong&gt;. Here do this-&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 { AuthCheck } from '@/app/hooks/AuthCheck';
import { userLoggedOut } from '@/app/reduxStore/features/auth/authSlice';
import Link from 'next/link';
import { useRouter } from 'next/navigation';
import { useDispatch } from 'react-redux';
import ComingSoon from "../icons/ComingSoon";
import Community from "../icons/Community";
import Friends from "../icons/Friends";
import Home from "../icons/Home";
import Logout from "../icons/Logout";
import MakeMovie from "../icons/MakeMovie";
import Media from "../icons/Media";
import MovieLogo from "../icons/MovieLogo";
import Profile from "../icons/Profile";
import Settings from "../icons/Settings";

const LiftSideBar = () =&amp;gt; {
  const isAuthenticated = AuthCheck();
  const dispatch = useDispatch();
  const router = useRouter();

  const logout = () =&amp;gt; {
    dispatch(userLoggedOut());
    localStorage.clear();
    router.push("/login");
  };

  return (
    &amp;lt;aside className=" w-1/6 py-10 pl-10  min-w-min  border-r border-gray-300 dark:border-zinc-700  hidden md:block "&amp;gt;
      &amp;lt;Link href="/"&amp;gt;
        &amp;lt;div className=" font-bold text-lg flex items-center gap-x-3"&amp;gt;
          &amp;lt;MovieLogo /&amp;gt;
          &amp;lt;div className="tracking-wide dark:text-white"&amp;gt;
            RMovie&amp;lt;span className="text-red-600"&amp;gt;.&amp;lt;/span&amp;gt;
          &amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
      &amp;lt;/Link&amp;gt;

      &amp;lt;div className="mt-12 flex flex-col gap-y-4 text-gray-500 fill-gray-500 text-sm"&amp;gt;
        &amp;lt;div className="text-gray-400/70  font-medium uppercase"&amp;gt;Menu&amp;lt;/div&amp;gt;
        &amp;lt;Link 
          href="/"
          className="flex items-center space-x-2 py-1 dark:text-white  font-semibold  border-r-4 border-r-red-600 pr-20 "
        &amp;gt;
          &amp;lt;Home /&amp;gt;
          &amp;lt;span&amp;gt;Home&amp;lt;/span&amp;gt;
        &amp;lt;/Link&amp;gt;

        &amp;lt;Link 
          href="/ai-make-movie"
          className="flex items-center space-x-2 py-1  group hover:border-r-4 hover:border-r-red-600 hover:font-semibold dark:hover:text-white"
        &amp;gt;
         &amp;lt;MakeMovie /&amp;gt;
          &amp;lt;span&amp;gt;Ai Make Movie&amp;lt;/span&amp;gt;
        &amp;lt;/Link&amp;gt;
        &amp;lt;Link 
          href="/manual-make-movie"
          className="flex items-center space-x-2 py-1  group hover:border-r-4 hover:border-r-red-600 hover:font-semibold dark:hover:text-white"
        &amp;gt;
         &amp;lt;MakeMovie /&amp;gt;
          &amp;lt;span&amp;gt;Manual Make Movie&amp;lt;/span&amp;gt;
        &amp;lt;/Link&amp;gt;

        &amp;lt;a
          className=" flex items-center space-x-2 py-1  group hover:border-r-4 hover:border-r-red-600 hover:font-semibold dark:hover:text-white "
          href="#"
        &amp;gt;
          &amp;lt;Community /&amp;gt;
          &amp;lt;span&amp;gt;Community&amp;lt;/span&amp;gt;
        &amp;lt;/a&amp;gt;
        &amp;lt;a
          className=" flex items-center space-x-2 py-1  group hover:border-r-4 hover:border-r-red-600 hover:font-semibold dark:hover:text-white "
          href="#"
        &amp;gt;
          &amp;lt;ComingSoon /&amp;gt;
          &amp;lt;span&amp;gt;Coming Soon&amp;lt;/span&amp;gt;
        &amp;lt;/a&amp;gt;

        &amp;lt;div className="mt-8 text-gray-400/70  font-medium uppercase"&amp;gt;
          Social
        &amp;lt;/div&amp;gt;
        &amp;lt;a
          className=" flex items-center space-x-2 py-1  group hover:border-r-4 hover:border-r-red-600 hover:font-semibold dark:hover:text-white "
          href="#"
        &amp;gt;
          &amp;lt;Profile /&amp;gt;
          &amp;lt;span&amp;gt;Profile&amp;lt;/span&amp;gt;
        &amp;lt;/a&amp;gt;
        &amp;lt;a
          className=" flex items-center space-x-2 py-1  group hover:border-r-4 hover:border-r-red-600 hover:font-semibold dark:hover:text-white "
          href="#"
        &amp;gt;
          &amp;lt;Friends /&amp;gt;
          &amp;lt;span&amp;gt;Friends&amp;lt;/span&amp;gt;
        &amp;lt;/a&amp;gt;
        &amp;lt;Link
          className=" flex items-center space-x-2 py-1  group hover:border-r-4 hover:border-r-red-600 hover:font-semibold dark:hover:text-white "
          href="/make-category"
        &amp;gt;
          &amp;lt;Media /&amp;gt;
          &amp;lt;span&amp;gt;Make Category&amp;lt;/span&amp;gt;
        &amp;lt;/Link&amp;gt;

        &amp;lt;div className="mt-8 text-gray-400/70  font-medium uppercase"&amp;gt;
          General
        &amp;lt;/div&amp;gt;
        &amp;lt;a
          className=" flex items-center space-x-2 py-1  group hover:border-r-4 hover:border-r-red-600 hover:font-semibold dark:hover:text-white "
          href="#"
        &amp;gt;
          &amp;lt;Settings /&amp;gt;
          &amp;lt;span&amp;gt;Settings&amp;lt;/span&amp;gt;
        &amp;lt;/a&amp;gt;

        { isAuthenticated &amp;amp;&amp;amp; (
        &amp;lt;a
          className=" flex items-center space-x-2 py-1  group hover:border-r-4 hover:border-r-red-600 hover:font-semibold dark:hover:text-white"
          href="#"
          onClick={logout}
        &amp;gt;
          &amp;lt;Logout /&amp;gt;
          &amp;lt;span&amp;gt;Logout&amp;lt;/span&amp;gt;
        &amp;lt;/a&amp;gt;
         )}

        { !isAuthenticated &amp;amp;&amp;amp; (
          &amp;lt;Link href="/login"
          className=" flex items-center space-x-2 py-1  group hover:border-r-4 hover:border-r-red-600 hover:font-semibold dark:hover:text-white"
        &amp;gt;
          &amp;lt;Logout /&amp;gt;
          &amp;lt;span&amp;gt;login {AuthCheck}&amp;lt;/span&amp;gt;
        &amp;lt;/Link&amp;gt;
        )}

      &amp;lt;/div&amp;gt;
    &amp;lt;/aside&amp;gt;
  );
};

export default LiftSideBar;

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

&lt;/div&gt;



&lt;p&gt;Here we have Two action hook. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Login Button &lt;/li&gt;
&lt;li&gt;Logout Button. &lt;/li&gt;
&lt;/ol&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%2Fa4iyjk0clb1wupwkj68m.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%2Fa4iyjk0clb1wupwkj68m.png" alt="Image description" width="470" height="170"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step-3 : Category Api Setup&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Go to reduxStore/features/category folder and create this file&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;categoryApi.js&lt;/li&gt;
&lt;li&gt;categorySlice.js&lt;/li&gt;
&lt;/ol&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%2F24vy3ivooc0niybo5lj7.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%2F24vy3ivooc0niybo5lj7.png" alt="Image description" width="488" height="461"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;categoryApi.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { apiSlice } from "../api/apiSlice";

export const categoryApi = apiSlice.injectEndpoints({
    endpoints: (builder) =&amp;gt; ({
        categoryWiseMovies: builder.query({
            query: () =&amp;gt;
                `/category-wise-movies`,

        }),
        allCategories: builder.query({
            query: () =&amp;gt;
                `/all-category`,

        }),
        categoryStore: builder.mutation({
            query: (data) =&amp;gt; ({
                url: "/category-store",
                method: "POST",
                body: data,
            }),
        })
    }),
});

export const { useCategoryWiseMoviesQuery, useAllCategoriesQuery, useCategoryStoreMutation} = categoryApi;

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

&lt;/div&gt;



&lt;p&gt;Here we have Three end point. There are&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;/category-wise-movies&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/all-category&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/category-store&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;categorySlice.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { createSlice } from "@reduxjs/toolkit";

const initialState = {
    topMovies: [],

};

const categorySlice = createSlice({
    name: "movie",
    initialState,
    reducers: {
        topMovies: (state, action) =&amp;gt; {
            state.topMovies = action.payload;

        }

    },
});

export const { topMovies} = categorySlice.actions;
export default categorySlice.reducer;

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

&lt;/div&gt;



&lt;p&gt;Here we have one action “topMovies”. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step-4: Category Page Setup and Others&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Go to make-category folder and we can see page.js, now write this-&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;page.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import LeftSideBar from "../component/common/LeftSideBar";
import RightSideBar from "../component/common/RightSideBar";
import AiFormInput from "../component/make-category/FormInput";
import ProtectedRoute from "../hooks/ProtectedRoute";

const Page = () =&amp;gt; {
  return (
    &amp;lt;ProtectedRoute&amp;gt;
    &amp;lt;div className="flex min-h-screen"&amp;gt;
      &amp;lt;LeftSideBar /&amp;gt;
      &amp;lt;div className=" flex-1 py-10  px-5 sm:px-10 "&amp;gt;
        &amp;lt;AiFormInput /&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;RightSideBar /&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;/ProtectedRoute&amp;gt;
  );
};

export default Page;

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

&lt;/div&gt;



&lt;p&gt;and go to component/make-category and see FormInput.js. Below this write-&lt;br&gt;
&lt;strong&gt;FormInput.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;'use client';
import { useCategoryStoreMutation } from "@/app/reduxStore/features/category/categoryApi";
import Image from 'next/image';
import { useRouter } from 'next/navigation';
import { useState } from "react";

const FormInput = () =&amp;gt; {
  const [categoryStore] = useCategoryStoreMutation();
  const router = useRouter();
  const [categoryData, setCategoryData] = useState({
    title: '',
    image: null,
  });

  const handleChange = (e) =&amp;gt; {
    const { name, value } = e.target;
    setCategoryData({ ...categoryData, [name]: value });
  };

  const handleFileChange = (e) =&amp;gt; {
    const file = e.target.files[0];
    setCategoryData({ ...categoryData, image: file });
  };

  const handleSubmit = async (e) =&amp;gt; {
    e.preventDefault();

    const formData = new FormData();
    formData.append('name', categoryData.title);
    formData.append('image', categoryData.image);
    console.log('categry submit form', categoryData)

    try {
      const response = await categoryStore(formData);
      // Handle the success response
      console.log('Response from server:', response.data);
      // Assuming you want to reset the form after successful submission
      setCategoryData({
        name: '',
        image: null,
      });

      router.push("/");

    } catch (error) {
      console.error('Error saving the movie:', error);
    }
  };
  return (
    &amp;lt;div className="bg-gray-200 p-5 rounded-md dark:bg-black"&amp;gt;
      &amp;lt;div className="text-center mb-8 relative"&amp;gt;
        &amp;lt;h1 className="text-2xl font-bold text-gray-700 mb-3 dark:text-white"&amp;gt;
          Create Category
        &amp;lt;/h1&amp;gt;

        &amp;lt;Image
          src="/AS0007464_07.gif"
          alt="form"
          className="rounded-full  absolute -top-5 right-0 sm::hidden"
          width={105}
          height={105}

        /&amp;gt;
      &amp;lt;/div&amp;gt;

      &amp;lt;form onSubmit={handleSubmit}&amp;gt;
        &amp;lt;div className="mx-10 px-10 py-16 bg-gray-400 dark:bg-black dark:border rounded-md"&amp;gt;
          &amp;lt;div className="mb-6"&amp;gt;
            &amp;lt;label
              htmlFor="large-input"
              className="block mb-2 text-sm font-medium text-gray-900 dark:text-white"
            &amp;gt;
              Category Name
            &amp;lt;/label&amp;gt;
            &amp;lt;input
              type="text"
              id="large-input"
              className="block w-full p-4 text-gray-900 border border-gray-300 rounded-lg bg-gray-50 sm:text-md focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
              placeholder="Type your Category name..."
              name="title"
              onChange={handleChange}
            /&amp;gt;
          &amp;lt;/div&amp;gt;
          &amp;lt;div className="mb-6"&amp;gt;
            &amp;lt;label
              htmlFor="large-input"
              className="block mb-2 text-sm font-medium text-gray-900 dark:text-white"
            &amp;gt;
              Select Category Image
            &amp;lt;/label&amp;gt;
            &amp;lt;input
              type="file"
              id="large-input"
              className="block w-full p-4 text-gray-900 border border-gray-300 rounded-lg bg-gray-50 sm:text-md focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
              name="image"
              onChange={handleFileChange}
            /&amp;gt;
          &amp;lt;/div&amp;gt;
          &amp;lt;div className="text-right"&amp;gt;
            &amp;lt;button
              type="submit"
              className="bg-black text-white p-3 rounded-md dark:border"
            &amp;gt;
              Make Category
            &amp;lt;/button&amp;gt;
          &amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
      &amp;lt;/form&amp;gt;

    &amp;lt;/div&amp;gt;
  );
};

export default FormInput;

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

&lt;/div&gt;



&lt;p&gt;Now &lt;strong&gt;“/make-category”&lt;/strong&gt; URL show this page and we can create category.&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%2Fjnr0ic4kz4ascqckvrnz.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%2Fjnr0ic4kz4ascqckvrnz.png" alt="Image description" width="800" height="376"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step-5: movie Api Setup&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Go to reduxStore/features/movie folder and create this file&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;movieApi.js&lt;/li&gt;
&lt;li&gt;movieSlice.js&lt;/li&gt;
&lt;/ol&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%2Fmc8nldf927e2pnxy4eyb.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%2Fmc8nldf927e2pnxy4eyb.png" alt="Image description" width="483" height="455"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;movieApi.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { apiSlice } from "../api/apiSlice";

export const moviesApi = apiSlice.injectEndpoints({
    endpoints: (builder) =&amp;gt; ({
        topMovies: builder.query({
            query: () =&amp;gt;
                `/top-movies`,
        }),
        manualMovieStore: builder.mutation({
            query: (data) =&amp;gt; ({
                url: "/movie-store",
                method: "POST",
                body: data,
            }),
        }),

        aiMovieStore: builder.mutation({

            query: (data) =&amp;gt; ({

                url: "/ai-movie-store",
                method: "POST",
                body: data,

            }),
            async onQueryStarted(arg, { queryFulfilled, dispatch }) {
               console.log('redux', arg)
            },
        }),

    }),
});

export const { useTopMoviesQuery, useManualMovieStoreMutation, useAiMovieStoreMutation} = moviesApi;

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

&lt;/div&gt;



&lt;p&gt;Here we have Three end points. There are&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;"/top-movies"&lt;/li&gt;
&lt;li&gt;"/movie-store"&lt;/li&gt;
&lt;li&gt;"/ai-movie-store"&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;movieSlice.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { createSlice } from "@reduxjs/toolkit";

const initialState = {
    topMovies: [],
    aiMovieData:{},
    sampleData:"sdfsf sdfsf"

};

const movieSlice = createSlice({
    name: "movie",
    initialState,
    reducers: {
        topMovies: (state, action) =&amp;gt; {
            state.topMovies = action.payload;

        },
        aiMovieData:(state, action) =&amp;gt;{
            console.log('redux movie')
            state.aiMovieData = action.payload;
        }

    },
});

export const { topMovies, aiMovieData} = movieSlice.actions;
export default movieSlice.reducer;

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

&lt;/div&gt;



&lt;p&gt;Here we have Two actions. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;topMovies&lt;/li&gt;
&lt;li&gt;aiMovieData&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Step-6: Manual Movie Page Setup and Others&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Go to manual-make-movie folder and see page.js file. Write this code-&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import LeftSideBar from "../component/common/LeftSideBar";
import RightSideBar from "../component/common/RightSideBar";
import FormInput from "../component/manual-make-movie/FormInput";

const Page = () =&amp;gt; {
  return (
    &amp;lt;div className="flex min-h-screen"&amp;gt;
      &amp;lt;LeftSideBar /&amp;gt;
      &amp;lt;div className=" flex-1 py-10  px-5 sm:px-10 "&amp;gt;
        &amp;lt;FormInput /&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;RightSideBar /&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};

export default Page;

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

&lt;/div&gt;



&lt;p&gt;Now go to component/manual-make-movie and write this&lt;br&gt;
&lt;strong&gt;FormInput.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;'use client';
import { useAllCategoriesQuery } from "@/app/reduxStore/features/category/categoryApi";
import { useManualMovieStoreMutation } from "@/app/reduxStore/features/movie/moviesApi";
import Image from 'next/image';
import { useRouter } from 'next/navigation';
import { useState } from "react";

const FormInput = () =&amp;gt; {
  const { data, isLoading, isError } = useAllCategoriesQuery();
  const [manualMovieStore, { isSuccess }] = useManualMovieStoreMutation();
  const router = useRouter();
  console.log("all manualMovieStore", manualMovieStore)

  const [movieData, setMovieData] = useState({
    title: '',
    category_id: '',
    description: '',
    image: null, 
  });

  const handleChange = (e) =&amp;gt; {
    const { name, value } = e.target;
    setMovieData({ ...movieData, [name]: value });
  };

  const handleFileChange = (e) =&amp;gt; {
    const file = e.target.files[0];
    setMovieData({ ...movieData, image: file });
  };

  const handleSubmit = async (e) =&amp;gt; {
    e.preventDefault();

    const formData = new FormData();
    formData.append('title', movieData.title);
    formData.append('category_id', movieData.category_id);
    formData.append('description', movieData.description);
    formData.append('image', movieData.image);
    console.log('form submit', movieData)
    try {
      const response = await manualMovieStore(formData);
      // Handle the success response
      console.log('Response from server:', response.data);
      // Assuming you want to reset the form after successful submission
      setMovieData({
        title: '',
        category_id: '',
        description: '',
        image: null,
      });
      router.push("/");
    } catch (error) {
      // Handle the error
      console.error('Error saving the movie:', error);
    }
  };

  if (isLoading) {
    return &amp;lt;div&amp;gt;Loading...&amp;lt;/div&amp;gt;;
  }

  if (isError) {
    return &amp;lt;div&amp;gt;Error fetching categories.&amp;lt;/div&amp;gt;;
  }
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;div className="text-center mb-8 relative"&amp;gt;
        &amp;lt;h1 className="text-2xl font-bold text-gray-700 mb-3 dark:text-white"&amp;gt;
          Manual Movie Maker
        &amp;lt;/h1&amp;gt;

        &amp;lt;Image
                src="/storytelling-08.gif"
                alt="input"
                className="rounded-full w-48 h-48 absolute -top-5 right-0 sm::hidden"
                width={200}
                height={200}
            /&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;form onSubmit={handleSubmit}&amp;gt;
        &amp;lt;div className="mx-10 px-10 py-16 bg-gray-400 dark:bg-black dark:border rounded-md"&amp;gt;
          &amp;lt;div className="mb-6"&amp;gt;
            &amp;lt;label
              htmlFor="large-input"
              className="block mb-2 text-sm font-medium text-gray-900 dark:text-white"
            &amp;gt;
              Movie Title
            &amp;lt;/label&amp;gt;
            &amp;lt;input
              type="text"
              id="large-input"
              className="block w-full p-4 text-gray-900 border border-gray-300 rounded-lg bg-gray-50 sm:text-md focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
              placeholder="Type your Movie Title..."
              name="title"
              onChange={handleChange}

            /&amp;gt;
          &amp;lt;/div&amp;gt;
          &amp;lt;div className="mb-6"&amp;gt;
            &amp;lt;label
              htmlFor="base-input"
              className="block mb-2 text-sm font-medium text-gray-900 dark:text-white"
            &amp;gt;
              Movie Category
            &amp;lt;/label&amp;gt;
            &amp;lt;select
              name="category_id"
              onChange={handleChange}
              id="category"
              className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
            &amp;gt;
              &amp;lt;option value=""&amp;gt;Choose category&amp;lt;/option&amp;gt;
              {data &amp;amp;&amp;amp; data.data?.map((category) =&amp;gt; (
                &amp;lt;option key={category._id} value={category._id}&amp;gt;
                  {category.name}
                &amp;lt;/option&amp;gt;
              ))}
            &amp;lt;/select&amp;gt;
          &amp;lt;/div&amp;gt;
          &amp;lt;div className="mb-6"&amp;gt;
            &amp;lt;label
              htmlFor="message"
              className="block mb-2 text-sm font-medium text-gray-900 dark:text-white"
            &amp;gt;
              Movie Short Description
            &amp;lt;/label&amp;gt;
            &amp;lt;textarea
              id="message"
              rows={4}
              className="block p-2.5 w-full text-sm text-gray-900 bg-gray-50 rounded-lg border border-gray-300 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
              placeholder="Type Movie short description..."
              v-model="movieData.description"
              defaultValue={""}
              name="descriptin"
              onChange={handleChange}
            /&amp;gt;
          &amp;lt;/div&amp;gt;
          &amp;lt;div className="mb-6"&amp;gt;
            &amp;lt;label
              htmlFor="large-input"
              className="block mb-2 text-sm font-medium text-gray-900 dark:text-white"
            &amp;gt;
              Select Movie image
            &amp;lt;/label&amp;gt;
            &amp;lt;input
              type="file"
              id="large-input"
              className="block w-full p-4 text-gray-900 border border-gray-300 rounded-lg bg-gray-50 sm:text-md focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
              placeholder="Type your Movie Title..."
              name="image"
              onChange={handleFileChange}
            /&amp;gt;
          &amp;lt;/div&amp;gt;
          &amp;lt;div className="text-right"&amp;gt;
            &amp;lt;button
              type="submit"
              className="bg-black text-white p-3 rounded-md dark:border"
            &amp;gt;
              Make Movie
            &amp;lt;/button&amp;gt;
          &amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
      &amp;lt;/form&amp;gt;

    &amp;lt;/div&amp;gt;
  );
};

export default FormInput;

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

&lt;/div&gt;



&lt;p&gt;Now we are making manual movie form.  If you hit “/manual-make-movie” URL then you see this page.&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%2Fj9o9sue9u0uk4s9yriid.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%2Fj9o9sue9u0uk4s9yriid.png" alt="Image description" width="800" height="380"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can now create any movie using this form.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step-7 : Home Page setup&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Go to app folder and see page.js file. Write this code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import LeftSideBar from "./component/common/LeftSideBar";
import RightSideBar from "./component/common/RightSideBar";
import CategoryWiseMovies from "./component/index/CategoryWiseMovies";
import HeroSection from "./component/index/HeroSection";
import TopMovies from "./component/index/TopMovies";

export default function Home() {
  return (
    &amp;lt;div className="flex min-h-screen"&amp;gt;
    &amp;lt;LeftSideBar /&amp;gt;
    &amp;lt;div className=" flex-1 py-10  px-5 sm:px-10 "&amp;gt;
      &amp;lt;HeroSection /&amp;gt;
      &amp;lt;TopMovies /&amp;gt;
      &amp;lt;CategoryWiseMovies /&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;RightSideBar /&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}

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

&lt;/div&gt;



&lt;p&gt;Now Go to component/index Folder and see TipMovie.js file. Write below this code-&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 { useTopMoviesQuery } from "@/app/reduxStore/features/movie/moviesApi";
import Image from 'next/image';
import ImdbLogo from "../icons/ImdbLogo";
import NextPrev from "../icons/NextPrev";

const TopMovies = () =&amp;gt; {
  const { data, error, isLoading } = useTopMoviesQuery();
  console.log("movie data", data)

  if (isLoading) {
      return &amp;lt;div&amp;gt;Loading...&amp;lt;/div&amp;gt;;
  }

  if (error) {
    return &amp;lt;div&amp;gt;Error: {error.message}&amp;lt;/div&amp;gt;;
  }

  const getRandomNumber = () =&amp;gt; {
    return Math.floor(Math.random() * 10) + 1;
  };

  return (
    &amp;lt;section className="mt-9 bg-lime-300 dark:bg-rose-500 p-5 rounded-md"&amp;gt;
      &amp;lt;div className="flex items-center justify-between"&amp;gt;
        &amp;lt;span className="font-semibold text-gray-700 text-base dark:text-white"&amp;gt;
          My Favourite Movies and Collections
        &amp;lt;/span&amp;gt;
        &amp;lt;div className="flex items-center space-x-2 fill-gray-500"&amp;gt;
          &amp;lt;NextPrev /&amp;gt;
        &amp;lt;/div&amp;gt;
      &amp;lt;/div&amp;gt;

      &amp;lt;div className="mt-4 grid grid-cols-2  sm:grid-cols-4 gap-x-5 gap-y-5"&amp;gt;
        {data.data &amp;amp;&amp;amp; data.data.map((movie, index) =&amp;gt; (
          &amp;lt;div
            key={index}
            className="flex flex-col rounded-xl overflow-hidden aspect-square border dark:border-zinc-600"
          &amp;gt;


            &amp;lt;div className="w-full h-1/5 bg-white dark:bg-zinc-800 dark:text-white px-3 flex items-center justify-between border-t-2 border-t-red-600"&amp;gt;
              &amp;lt;span className="capitalize font-medium truncate"&amp;gt;{movie.title}&amp;lt;/span&amp;gt;
              &amp;lt;div className="flex space-x-2 items-center text-xs"&amp;gt;
                &amp;lt;ImdbLogo /&amp;gt;
                &amp;lt;span&amp;gt;{getRandomNumber()}&amp;lt;/span&amp;gt;
              &amp;lt;/div&amp;gt;
            &amp;lt;/div&amp;gt;
            &amp;lt;Image
                src={movie.image}
                className="h-4/5 object-cover w-full"
                alt={movie.title}
                width={105} 
                height={105} 
                layout="responsive"
            /&amp;gt;
          &amp;lt;/div&amp;gt;
        ))}
      &amp;lt;/div&amp;gt;
      {isLoading &amp;amp;&amp;amp; isLoading}
      {error &amp;amp;&amp;amp; error}
    &amp;lt;/section&amp;gt;
  );
};

export default TopMovies;

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

&lt;/div&gt;



&lt;p&gt;Now same Folder we can see CategoryWiseMovies.js file. Write this code-&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/* eslint-disable react/jsx-key */
'use client';
import { useCategoryWiseMoviesQuery } from "@/app/reduxStore/features/category/categoryApi";
import Image from 'next/image';
import ImdbLogo from "../icons/ImdbLogo";
import NextPrev from "../icons/NextPrev";

const CategoryWiseMovies = () =&amp;gt; {
  const { data, error, isLoading } = useCategoryWiseMoviesQuery();
  console.log('category wise movie data', data)

  const getRandomColor = () =&amp;gt; {
    const colors = ['#FF5733', '#33FF57', '#5733FF', '#33FFFF', '#FF33FF', '#FFFF33'];
    return colors[Math.floor(Math.random() * colors.length)];
  };
  const getRandomNumber = () =&amp;gt; {
    return Math.floor(Math.random() * 10) + 1;
  };
  if (isLoading) {
    return &amp;lt;div&amp;gt;Loading...&amp;lt;/div&amp;gt;;
  }

  if (error) {
    return &amp;lt;div&amp;gt;Error: {error.message}&amp;lt;/div&amp;gt;;
  }

  return (
    &amp;lt;&amp;gt;
      {data.data.map((category, indexOne) =&amp;gt; (
        &amp;lt;section className="mt-9 bg-blue-400 dark:bg-black p-5 rounded-md" style={{ backgroundColor: getRandomColor() }} key={indexOne}&amp;gt;
          &amp;lt;div className="flex items-center justify-between"&amp;gt;
            &amp;lt;span className="font-semibold text-gray-700 text-base dark:text-white"&amp;gt;{category.name} Movies&amp;lt;/span&amp;gt;
            &amp;lt;div className="flex items-center space-x-2 fill-gray-500"&amp;gt;
              &amp;lt;NextPrev /&amp;gt;
            &amp;lt;/div&amp;gt;
          &amp;lt;/div&amp;gt;

          &amp;lt;div className="mt-4 grid grid-cols-2 gap-y-5 sm:grid-cols-3 gap-x-5 "&amp;gt;
            {category.movies.map((movie, indexTwo) =&amp;gt; (
              &amp;lt;div className="flex flex-col rounded-xl overflow-hidden aspect-square border dark:border-zinc-600" key={indexTwo}&amp;gt;
                &amp;lt;div className="w-full h-1/5 bg-white dark:bg-zinc-800 dark:text-white px-3 flex items-center justify-between border-t-2 border-t-red-600"&amp;gt;
                  &amp;lt;span className="capitalize  font-medium truncate"&amp;gt;{movie.title}&amp;lt;/span&amp;gt;
                  &amp;lt;div className="flex space-x-2 items-center text-xs"&amp;gt;
                    &amp;lt;ImdbLogo /&amp;gt;
                    &amp;lt;span&amp;gt;{getRandomNumber()}&amp;lt;/span&amp;gt;
                  &amp;lt;/div&amp;gt;
                &amp;lt;/div&amp;gt;
                &amp;lt;Image
                  src={movie.image}
                  className=" h-4/5 object-cover w-full"
                  alt={movie.title}
                  width={105} 
                height={105} 
                layout="responsive"
                /&amp;gt;
              &amp;lt;/div&amp;gt;
            ))}

          &amp;lt;/div&amp;gt;

        &amp;lt;/section&amp;gt;
      ))}
    &amp;lt;/&amp;gt;
  );
};

export default CategoryWiseMovies;

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

&lt;/div&gt;



&lt;p&gt;Now ready home page. If we are hit &lt;a href="http://localhost:3000/" rel="noopener noreferrer"&gt;http://localhost:3000/&lt;/a&gt; then we can see our home page. &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%2Fap8an48x85e20goa0q8z.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%2Fap8an48x85e20goa0q8z.png" alt="Image description" width="800" height="377"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If your database is empty then you don't see any movie  😊&lt;/p&gt;

&lt;p&gt;Next we set up AI Prompt. Here is this Tutorial-&lt;/p&gt;

&lt;p&gt;AI Prompt setup on Nextjs. &lt;a href="https://dev.to/kamruzzaman/ai-prompt-setup-on-nextjs-2109"&gt;Link&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;full Project github&lt;br&gt;
&lt;strong&gt;Node&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://github.com/kamruzzamanripon/node-movie-api" rel="noopener noreferrer"&gt;https://github.com/kamruzzamanripon/node-movie-api&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;NextJs&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://github.com/kamruzzamanripon/next-movie-ui-with-node-api" rel="noopener noreferrer"&gt;https://github.com/kamruzzamanripon/next-movie-ui-with-node-api&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;NextJs UI&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://github.com/kamruzzamanripon/next-movie-ui" rel="noopener noreferrer"&gt;https://github.com/kamruzzamanripon/next-movie-ui&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's all. Happy Learning :) .&lt;br&gt;
[if it is helpful, giving a star to the repository 😇]&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>node</category>
      <category>nextjs</category>
      <category>mern</category>
    </item>
    <item>
      <title>Scaffolding redux-toolkit in NextJs</title>
      <dc:creator>syed kamruzzaman</dc:creator>
      <pubDate>Sun, 17 Dec 2023 19:41:25 +0000</pubDate>
      <link>https://dev.to/kamruzzaman/scaffolding-redux-toolkit-in-nextjs-1n2p</link>
      <guid>https://dev.to/kamruzzaman/scaffolding-redux-toolkit-in-nextjs-1n2p</guid>
      <description>&lt;p&gt;Previously you saw, how to make API via Node. Here is this &lt;a href="https://dev.tourl"&gt;tutorial&lt;/a&gt;. Now in this tutorial, we are focused on integrating this API in our Next.js App. Let's dive in!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;UI Design&lt;/strong&gt;&lt;br&gt;
Basic UI design I am already done for easy our task. Below is this UI project link. Here we use TailwindCss.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kamruzzamanripon/next-movie-ui" rel="noopener noreferrer"&gt;https://github.com/kamruzzamanripon/next-movie-ui&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this UI app, we can see the app folder, in which you see the page.js file. This is the home page and the other page shows folder-wise. Like make-category it means create category and its URL is /make-category. I was trying to make it simple to understand.&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%2Fk9x576aszqr5gl8oq0vi.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%2Fk9x576aszqr5gl8oq0vi.png" alt="Image description" width="506" height="1028"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step-1 : Install reduxt toolkit and other packages&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install @reduxjs/toolkit
npm install react-redux
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step-2 : Configure API Url&lt;/strong&gt;&lt;br&gt;
Open your &lt;strong&gt;next.config&lt;/strong&gt; and do this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module.exports = {
    reactStrictMode: true,
    images:{
      domains:['images.unsplash.com', 'via.placeholder.com', '127.0.0.1', 'laravelapi.kamruzzaman.xyz'],
    },
    env: {
      API_ROOT_URL:'http://localhost:8000/api',
      baseUrl:'http://127.0.0.1:8000/api/v1/frontend',


    },
  }

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

&lt;/div&gt;



&lt;p&gt;Here we defined  API_ROOT_URL and setup domains '127.0.0.1' for image.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step-3 : Make some folder&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In app folder we create reduxStore folder and in this folder we create below file&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;provider.js&lt;/li&gt;
&lt;li&gt;store.js&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;and make another folder like features And this inside this folder create the below folder and file&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;api [Folder]

&lt;ul&gt;
&lt;li&gt;apiSlice.js&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;auth [Folder]

&lt;ul&gt;
&lt;li&gt;authApi.js&lt;/li&gt;
&lt;li&gt;authSlice.js&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;category [Folder]

&lt;ul&gt;
&lt;li&gt;categoryApi.js&lt;/li&gt;
&lt;li&gt;categorySlice.js&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;movie [Folder]

&lt;ul&gt;
&lt;li&gt;moviesApi.js&lt;/li&gt;
&lt;li&gt;movieSlice.js&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&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%2Fkvyj02sht5llge53wgu1.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%2Fkvyj02sht5llge53wgu1.png" alt="Image description" width="511" height="1345"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we copy and paste the corresponding file of code&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Store.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

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

import { configureStore } from "@reduxjs/toolkit";
import { apiSlice } from "./features/api/apiSlice";
import authSliceReducer from "./features/auth/authSlice";
import counterReducer from './features/counter/counterSlice';
import movieSliceReducer from "./features/movie/movieSlice";

export const store = configureStore({
    reducer:{
        [apiSlice.reducerPath]: apiSlice.reducer,
        auth: authSliceReducer,
        movies: movieSliceReducer,
        conter: counterReducer
    },
    devTools: process.env.NODE_ENV !== "production",
    middleware: (getDefaultMiddlewares) =&amp;gt;
        getDefaultMiddlewares().concat(apiSlice.middleware),
})

Provider.js
'use client';

import { Provider } from "react-redux";
import { store } from "./store";

export function Providers({children}){
    return (
        &amp;lt;Provider store={store}&amp;gt;
            {children}
        &amp;lt;/Provider&amp;gt;
    )
}

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;apiSlice.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;'use client';
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";

// Function to get the auth token from localStorage
function getAuthToken() {
  if (typeof window !== 'undefined') {
    const authData = JSON.parse(localStorage.getItem("auth"));
    return authData?.accessToken;
  }
  return undefined;
}

export const apiSlice = createApi({
    reducerPath: "api",
    baseQuery: fetchBaseQuery({
        baseUrl: process.env.API_ROOT_URL,
        prepareHeaders: (headers, { getState }) =&amp;gt; {
            // Use the token from the state if available, otherwise try to get it from localStorage
            const token = getState()?.auth?.accessToken || getAuthToken();

            if (token) {
                headers.set("Authorization", `Bearer ${token}`);
            }

            return headers;
        },
    }),
    tagTypes: [],
    endpoints: (builder) =&amp;gt; ({}),
});


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

&lt;/div&gt;



&lt;p&gt;Here baseUrl, we already define in our next.config.js file. Also we set up of Authorization token. If API Url sends an Authorization token then we store headers for access to other pages.&lt;br&gt;
Now we go &lt;strong&gt;layout.js&lt;/strong&gt; file and do 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 { Inter } from 'next/font/google'
import Footer from './Footer'
import Header from './Header'
import './globals.css'
import { Providers } from './reduxStore/provider'

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

export const metadata = {
  title: 'Create Next App',
  description: 'Generated by create next app',
}

export default function RootLayout({ children }) {
  return (
    &amp;lt;html lang="en"&amp;gt;
      &amp;lt;body className={inter.className}&amp;gt;
        &amp;lt;Providers&amp;gt;
        &amp;lt;Header /&amp;gt;
        &amp;lt;main&amp;gt;{children}&amp;lt;/main&amp;gt;
        &amp;lt;Footer /&amp;gt;
        &amp;lt;/Providers&amp;gt;
      &amp;lt;/body&amp;gt;
    &amp;lt;/html&amp;gt;
  )
}

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

&lt;/div&gt;



&lt;p&gt;Here we wrapped up redux store in our app.&lt;br&gt;
Next we set up Authentication and Other API. Here is this Tutorial-&lt;/p&gt;

&lt;p&gt;API Setup in NextJs. &lt;a href="https://dev.to/kamruzzaman/api-setup-in-nextjs-3gen"&gt;Link&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;full Project github&lt;br&gt;
&lt;strong&gt;Node&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://github.com/kamruzzamanripon/node-movie-api" rel="noopener noreferrer"&gt;https://github.com/kamruzzamanripon/node-movie-api&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;NextJs&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://github.com/kamruzzamanripon/next-movie-ui-with-node-api" rel="noopener noreferrer"&gt;https://github.com/kamruzzamanripon/next-movie-ui-with-node-api&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;NextJs UI&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://github.com/kamruzzamanripon/next-movie-ui" rel="noopener noreferrer"&gt;https://github.com/kamruzzamanripon/next-movie-ui&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's all. Happy Learning :) .&lt;br&gt;
[if it is helpful, giving a star to the repository 😇]&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>nextjss</category>
      <category>node</category>
      <category>mern</category>
    </item>
    <item>
      <title>Making API Using Node and Express</title>
      <dc:creator>syed kamruzzaman</dc:creator>
      <pubDate>Sun, 17 Dec 2023 19:39:58 +0000</pubDate>
      <link>https://dev.to/kamruzzaman/making-api-using-node-and-express-4a9l</link>
      <guid>https://dev.to/kamruzzaman/making-api-using-node-and-express-4a9l</guid>
      <description>&lt;p&gt;In this tutorial, we are making API for a Movie Portal. Here we use NodeJs, Express-5.0, and other necessary Packages. We are Trying to Follow the MVC Pattern.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1 : Scaffolding&lt;/strong&gt; &lt;br&gt;
Open your terminal and type&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 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Fill up your required field. Then open your visual studio or any kind of editor. Create .env file type this-&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PORT= 8000
DATABASE_URL = "mongodb://localhost:27017"
IMAGE_BASE_URL = "http://127.0.0.1:8000"

DBNAME = "exress_movie_api"

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

&lt;/div&gt;



&lt;p&gt;Then create the following folders-&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;controllers&lt;/li&gt;
&lt;li&gt;db&lt;/li&gt;
&lt;li&gt;routes&lt;/li&gt;
&lt;li&gt;helpers&lt;/li&gt;
&lt;li&gt;middleware&lt;/li&gt;
&lt;li&gt;public / uploads

&lt;ul&gt;
&lt;li&gt;category&lt;/li&gt;
&lt;li&gt;movie&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&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%2Fqtxk788esd7zs1puhblg.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%2Fqtxk788esd7zs1puhblg.png" alt="Image description" width="689" height="506"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now install this app-&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;express&lt;/li&gt;
&lt;li&gt;cors&lt;/li&gt;
&lt;li&gt;dotenv&lt;/li&gt;
&lt;li&gt;joi&lt;/li&gt;
&lt;li&gt;bcryptjs&lt;/li&gt;
&lt;li&gt;jsonwebtoken&lt;/li&gt;
&lt;li&gt;mongoose&lt;/li&gt;
&lt;li&gt;multer&lt;/li&gt;
&lt;li&gt;nodemon&lt;/li&gt;
&lt;li&gt;uuid&lt;/li&gt;
&lt;/ol&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%2F72hh9259oi5izo9lmtuh.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%2F72hh9259oi5izo9lmtuh.png" alt="Image description" width="426" height="652"&gt;&lt;/a&gt;&lt;br&gt;
And here, in your package.json file add &lt;strong&gt;“type”: “module”&lt;/strong&gt; because we are using express-5.0. if you don’t do that in your .js file import is not work.&lt;br&gt;
After That, create an app.js file in your root folder. Here you type 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 cors from 'cors';
import dotenv from 'dotenv';
import express from 'express';
import connectiondb from './db/connectiondb.js';
dotenv.config();

const app = express();
const port = process.env.PORT || 8000;
const DATABASE_URL = process.env.DATABASE_URL || "mongodb:://localhost:27017";

//connection database
connectiondb(DATABASE_URL);

//app use for different purpose
app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended:true}))


app.listen(port, ()=&amp;gt;{
    console.log(`server listening at http://localhost:${port}`)
})

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

&lt;/div&gt;



&lt;p&gt;Now create db folder inside &lt;strong&gt;connectiondb.js&lt;/strong&gt; file and type 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 mongoose from 'mongoose';

//database connection
const connectiondb = async(DATABASE_URL)=&amp;gt;{
    try{
        const options = {
            dbName: process.env.DBNAME
        }

        const connectionResult = await mongoose.connect(DATABASE_URL, options);
        console.log(`connection to mongoDB on database: ${connectionResult.connections[0].name} at ${new Date().toDateString()}`);
    }catch(err){
        console.log(err);
    }
}

export default connectiondb;

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

&lt;/div&gt;



&lt;p&gt;Now last. Open your MongoDB and Create a Database. Database Name will be &lt;strong&gt;“express_movie_api”&lt;/strong&gt; and Collection Name is “movies”;&lt;br&gt;
Now open your terminal and type npm run dev. You can see 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%2Fmy1krm99l64o571xtk1a.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%2Fmy1krm99l64o571xtk1a.png" alt="Image description" width="800" height="137"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you see your database name and current date then your connection will be ok. You are now going to the next step.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step-2 : Model Defined&lt;/strong&gt;&lt;br&gt;
In your models folder make these files.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;User.js&lt;/li&gt;
&lt;li&gt;Category.js&lt;/li&gt;
&lt;li&gt;Movie.js&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And Type this. &lt;br&gt;
&lt;strong&gt;User.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

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

const DataSchema = new mongoose.Schema({
    name: {
        type: String,
        trim: true,
        required: true,
        maxlength: 32,
    },
    email: {
        type: String,
        trim: true,
        required: true,
        unique: true,
    },
    password: {
        type: String,
        required: true
    },
},{ timestamps: true, versionKey:false })


const User = mongoose.model('User', DataSchema);

export default User;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Category.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

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

const DataSchema = new mongoose.Schema({
    name: {
        type: String,
        required: [true, 'Please enter name'],
        trim: true,
        maxLength: [100, 'Category name cannot exceed 100 characters']
    },

    image: { 
        type: Object, 
    },
},{ timestamps: true, versionKey:false })


const Category = mongoose.model('Category', DataSchema);

export default Category;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Movie.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

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

const DataSchema = new mongoose.Schema({
    title: {
        type: String,
        required: [true, 'Please enter name'],
        trim: true,
        maxLength: [100, 'Category name cannot exceed 100 characters']
    },
    category_id: {
        type: mongoose.Types.ObjectId,
        ref: "Category",
        required: true
    },
    descriptin: {
        type: String,
        trim: true,
    },
    image: { 
        type: String, 
        required: true
    },
},{ timestamps: true, versionKey:false })


const Movie = mongoose.model('Movie', DataSchema);

export default Movie;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step-3 : Helpers Function define&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Now you create some auxiliary function. This functions as some kind of middleware. Create this-&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;bcryp.js&lt;/li&gt;
&lt;li&gt;jwt.js&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;bcryp.js&lt;/strong&gt; Function Helping client password encoded and decoded.&lt;br&gt;
&lt;/p&gt;

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

export const hashMaker = (str)=&amp;gt; {
    const salt = bcrypt.genSaltSync(10);
    return bcrypt.hashSync(str, salt);
}

export const matchData = (str, hash)=&amp;gt; {
    return bcrypt.compareSync(str, hash);
}

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;jwt.js&lt;/strong&gt; function helping Jwt token create and decoded this token.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import jwt from 'jsonwebtoken';
const secret = "@#$%^&amp;amp;*&amp;amp;*"

export const createToken = (payload)=&amp;gt; {
    return jwt.sign(payload, secret, { expiresIn: '1d' }); //1day
}

export const decodeToken = (payload)=&amp;gt; {
    return jwt.verify(payload, secret);
}

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step-4: Making Some Middleware.&lt;/strong&gt;&lt;br&gt;
In your middleware folder create some middleware file. Like this-&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;auth.js&lt;/li&gt;
&lt;li&gt;fileFolderName.js&lt;/li&gt;
&lt;li&gt;fileUpload.js&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;auth.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { decodeToken } from '../helpers/jwt.js';

const auth = (req, res, next)=&amp;gt; {
    try {
        const token = req.headers.authorization.split(' ')[1];
        req.user = decodeToken(token);
        //console.log(req.user)
        next();
    } catch (err) {
        res.status(400).send('Authentication Failed')
    }
}
export default auth;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;fileFolderName.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const fileFloderName = (folderName) =&amp;gt;{
    return ( req, res, next)=&amp;gt;{
        req.folderName = folderName;
        next();
    }
}

export default fileFloderName

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;fileUpload.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

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

const storage = multer({
  storage: multer.diskStorage({
    destination: function (req, file, cb) {
      const folderName = req.folderName ?? file.fieldname;
      cb(null, `public/uploads/${folderName}`);
    },
    filename: function (req, file, cb) {
      cb(null, `${Date.now()}-${file.originalname}`);
    },
  }),
  fileFilter: function (req, file, cb) {
    const allowedMimeTypes = ['image/jpeg', 'image/png']; // Specify the allowed image file types

    if (allowedMimeTypes.includes(file.mimetype)) {
      cb(null, true); // Accept the file
    } else {
      cb(new Error('Invalid file type. Only JPEG and PNG files are allowed.')); // Reject the file
    }
  },
  limits: {
    fileSize: 2 * 1024 * 1024, // Set the maximum file size (2MB in this example)
  },
});

export default storage;

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

&lt;/div&gt;



&lt;p&gt;After that Create validation folder for validation field and then create this file&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;userSingupValidator.js&lt;/li&gt;
&lt;li&gt;categoryStoreValidator.js&lt;/li&gt;
&lt;li&gt;movieStoreValidator.js&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;userSingupValidator.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

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

export const userSignupValidator = (req, res, next) =&amp;gt; {
  const schema = Joi.object({
    name: Joi.string().required().messages({
      'any.required': 'Name is required',
    }),
    email: Joi.string().email().required().messages({
      'string.email': 'Email must be a valid email address',
      'any.required': 'Email is required',
    }),
    password: Joi.string()
      .min(6)
      .required()
      .pattern(new RegExp('^[a-zA-Z0-9]{3,30}$'))
      .messages({
        'string.min': 'Password must be at least 6 characters',
        'any.required': 'Password is required',
        'string.pattern.base': 'Password must contain only alphanumeric characters',
      }),
      password_confirmation: Joi.string()
      .valid(Joi.ref('password'))
      .required()
      .messages({
        'any.only': 'Password confirmation must match the password',
        'any.required': 'Password confirmation is required',
      }),
      job: Joi.string().optional(),

  });

  const { error } = schema.validate(req.body);
  if (error) {
    const errorMessage = error.details[0].message;
    return res.status(400).json({ error: errorMessage });
  }

  next();
};

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;categoryStoreValidator.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

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

export const categoryStoreValidator = (req, res, next) =&amp;gt; {
  const schema = Joi.object({

    name: Joi.string()
    .required().
    messages({
        'string.name': 'Name is required'
       }),

  });

  const { error } = schema.validate(req.body);
  if (error) {
    const errorMessage = error.details[0].message;
    return res.status(400).json({ error: errorMessage });
  }

  next();
};

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;movieStoreValidator.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

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

export const movieStoreValidator = (req, res, next) =&amp;gt; {
  const schema = Joi.object({

    title: Joi.string()
    .required().
    messages({
        'string.name': 'Name is required'
       }),
    category_id: Joi.string()
    .required().
    messages({
        'string.category_id': 'Category Name is required'
    }), 
    image: Joi.string()
    .required().
    messages({
        'string.image': 'image is required'
    }), 


  });

  const { error } = schema.validate(req.body);
  if (error) {
    const errorMessage = error.details[0].message;
    return res.status(400).json({ error: errorMessage });
  }

  next();
};

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step-5 : Route define&lt;/strong&gt;&lt;br&gt;
In your routes folder create this file-&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;rootRoute.js&lt;/li&gt;
&lt;li&gt;authRoute.js&lt;/li&gt;
&lt;li&gt;categoryRoute.js&lt;/li&gt;
&lt;li&gt;movieRoute.js&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;rootRoute.js&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;In this file you add this code-&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import express from 'express';
import multer from 'multer';
import CategoryRoute from './CategoryRoute.js';
import authRoute from './authRoute.js';
import movieRoute from './movieRoute.js';

const route = (app)=&amp;gt;{
    app.use(express.static("public/uploads/category"));
    app.use(express.static("public/uploads/movie"));

    app.use("/api", authRoute);
    app.use("/api", CategoryRoute);
    app.use("/api", movieRoute);

    //Multer Error File Handling
    app.use((err, req, res, next) =&amp;gt; {
        if (err instanceof multer.MulterError) {
        // Multer-specific errors
        return res.status(418).json({
            err_code: err.code,
            err_message: err.message,
        });
        } else {
        // Handling errors for any other cases from whole application
        return res.status(500).json({
            err_code: 409,
            err_message: "Something went wrong!",
        });
        }
    });

    //unknown route
    app.use('*', (req, res)=&amp;gt;{
        res.status(404).json({status:"fail", data:"Route does not exists"})
    })

}

export default route;

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

&lt;/div&gt;



&lt;p&gt;here first we define static folder for save image.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app.use(express.static("public/uploads/category"));
app.use(express.static("public/uploads/movie"));

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

&lt;/div&gt;



&lt;p&gt;Like category image and movie image. Then write error handling image function-&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//Multer Error File Handling
    app.use((err, req, res, next) =&amp;gt; {
        if (err instanceof multer.MulterError) {
        // Multer-specific errors
        return res.status(418).json({
            err_code: err.code,
            err_message: err.message,
        });
        } else {
        // Handling errors for any other cases from whole application
        return res.status(500).json({
            err_code: 409,
            err_message: "Something went wrong!",
        });
        }
    });

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

&lt;/div&gt;



&lt;p&gt;At the end we write unknown route handler function. If user didn’t write proper url then show  message &lt;strong&gt;“Route does not exists”&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//unknown route
    app.use('*', (req, res)=&amp;gt;{
        res.status(404).json({status:"fail", data:"Route does not exists"})
    })

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

&lt;/div&gt;



&lt;p&gt;Now go to &lt;strong&gt;app.js&lt;/strong&gt; file and add this line-&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import rootRoute from './routes/rootRoute.js';
rootRoute(app);

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

&lt;/div&gt;



&lt;p&gt;like this way-&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import cors from 'cors';
import dotenv from 'dotenv';
import express from 'express';
import connectiondb from './db/connectiondb.js';
import rootRoute from './routes/rootRoute.js';
dotenv.config();

const app = express();
const port = process.env.PORT || 8000;
const DATABASE_URL = process.env.DATABASE_URL || "mongodb:://localhost:27017";

//connection database
connectiondb(DATABASE_URL);

//app use for different purpose
app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended:true}))

rootRoute(app);

app.listen(port, ()=&amp;gt;{
    console.log(`server listening at http://localhost:${port}`)
})

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

&lt;/div&gt;



&lt;p&gt;Again we go to &lt;strong&gt;rootRoute.js&lt;/strong&gt; file. Here we first discuss about authRoute which we are importing from 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 authRoute from './authRoute.js';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;so, create &lt;strong&gt;authRoute.js&lt;/strong&gt; file in the routes folder and write this code-&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import express from 'express';
import AuthController from '../controllers/AuthController.js';
import auth from '../middleware/auth.js';
import { userSignupValidator } from '../middleware/validation/userSingupValidator.js';

const router = express.Router();

router.post('/register', userSignupValidator, AuthController.registration);
router.post('/login', AuthController.login);
router.post('/logout', AuthController.logout);
router.post('/change-password', auth, AuthController.changePassword);

export default router;

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

&lt;/div&gt;



&lt;p&gt;Then go to the controllers folder create &lt;strong&gt;AuthController.js&lt;/strong&gt; file and write 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 { hashMaker, matchData } from "../helpers/bcryp.js";
import { createToken } from "../helpers/jwt.js";
import User from "../models/User.js";

class UserController {

  static registration = async (req, res) =&amp;gt; {
    try {
      const { name, email, password, password_confirmation } = req.body;
      const existEmail = await User.findOne({ email }).lean().exec();
      if (existEmail) {
        return res.status(413).json({
          code: 201,
          message: "This Email is already used.",
        });
      }

      const hashPassword = hashMaker(password);
      const registerUser = await new User({
        name: name,
        email: email,
        password: hashPassword,
      }).save();
      console.log("userEmail", hashPassword);

      res.status(201).json({
        code: 201,
        message: "User registration Successfully.",
        payload: registerUser,
      });
    } catch (err) {
      console.log(err);
      res.status(500).json({
        code: 500,
        message: "Internal server error.",
      });
    }
  }

  static login = async (req, res) =&amp;gt;{
    try {
        const { email, password } = req.body;
        const existEmail = await User.findOne({ email }).lean().exec();
        //mail check
        if (!existEmail) {
          return res.status(413).json({
            code: 201,
            message: "crediential didn't match",
          });
        }

        const hashPassword = matchData(password, existEmail.password);
        //password check
        if(!hashPassword){
            return res.status(413).json({
                code: 201,
                message: "crediential didn't match",
              });
        } 

       const {_id, name} = existEmail
        const payload ={
            name,
            email,
            token: "Bearer " + createToken({ _id, email })
        }

        res.status(200).json({
            code: 200,
            message: "User Login Successfully.",
            payload
        });
      } catch (err) {
        console.log(err);
        res.status(500).json({
          code: 500,
          message: "Internal server error.",
        });
      }
  }

  static logout = (req, res)=&amp;gt;{
      try {
        // Clear the token from the cookie
        res.clearCookie('token');

        res.status(200).json({
          code: 200,
          message: 'User logged out successfully.',
        });
      } catch (err) {
        console.log(err);
        res.status(500).json({
          code: 500,
          message: "Internal server error.",
        });
      }

  }

  static changePassword = async(req, res)=&amp;gt;{
    const {password, password_confirmation } = req.body;
    try{
      const {_id} = req.user;
      if (password !== password_confirmation) {
        return res.status(413).json({
          code: 201,
          message: "crediential didn't match",
        });
      }
      const userInfo = await User.findById(_id);
      const hashPassword = hashMaker(password);
      userInfo.password = hashPassword;
      await userInfo.save();
      console.log(userInfo)
      //await User.updateOne({ _id: _id }, { $set: payload }, { upsert: false });

      res.status(200).json({
        code: 200,
        message: "passwrod Change Successfully.",

    });

    }catch(err){
      console.log(err);
      res.status(500).json({
        code: 500,
        message: "Internal server error.",
      });
    }
  }

}

export default UserController;

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

&lt;/div&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%2Fh5qorr1kr3pnqs1ma604.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%2Fh5qorr1kr3pnqs1ma604.png" alt="Image description" width="800" height="434"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Is your output similar to this congratulation, you have successfully user registration. Now we are testing the login route. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftuk3hdxnla23zn8xt1h7.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%2Ftuk3hdxnla23zn8xt1h7.png" alt="Image description" width="800" height="421"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you log in successfully then we can see the token. This token is a jwt token. We can now use this token as an authentication.  &lt;/p&gt;

&lt;p&gt;Now we go to again rootRoute.js and this time we are talking about CategoryRoute.js. So create this file and write this&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CategoryRoute.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import express from 'express';
import CategoryController from '../controllers/CategoryController.js';
import fileFolderName from '../middleware/fileFolderName.js';
import storage from '../middleware/fileUpload.js';
import { categoryStoreValidator } from "../middleware/validation/categoryStoreValidator.js";

const router = express.Router();

router.get("/all-category", CategoryController.allCategory);
router.get("/category-wise-movies", CategoryController.categoryWiseMovie);
router.get("/single-category/:categoryId", CategoryController.singleCategory);

router.post(
  "/category-store",
  //auth,
  categoryStoreValidator,
  fileFolderName("category"),
  storage.fields([{ name: "image", maxCount: 1 }]),
  CategoryController.store
);

router.put(
  "/category-update/:categoryId",
  //auth,
  categoryStoreValidator,
  fileFolderName("category"),
  storage.fields([{ name: "image", maxCount: 1 }]),
  CategoryController.update
);

router.delete(
  "/category-delete/:categoryId",
  //auth,
  //categoryStoreValidator,
  fileFolderName("category"),
  storage.fields([{ name: "image", maxCount: 1 }]),
  CategoryController.delete
);

// //find product by id
router.param("categoryId", CategoryController.categoryById);

export default router;

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

&lt;/div&gt;



&lt;p&gt;Here you see, we write router.param("categoryId", CategoryController.categoryById). This route is a special route, like when we call single route –&lt;br&gt;
router.get("/single-category/:categoryId", CategoryController.singleCategory);&lt;/p&gt;

&lt;p&gt;here this route we passed categoryId param. So this param first calls router. param route and after that call single-category route. It helps for reduce query. &lt;/p&gt;

&lt;p&gt;Now we go to the controllers folder create &lt;strong&gt;CategoryController.js&lt;/strong&gt; and write 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 fs from "fs";
import Category from "../models/Category.js";
import Movie from "../models/Movie.js";

class CategoryController {
  //find a Category by  id
  static categoryById = async (req, res, next, id) =&amp;gt; {
    const category = await Category.findById(id);

    if (!category) {
      return res.status(404).json({
        code: 404,
        message: "Category not found.",
      });
    }

    req.category = category;
    // console.log('cat result', req.category)
    next();
  };

  //all Category
  static allCategory = async (req, res) =&amp;gt; {
    try {
      const imageBaseURL = process.env.IMAGE_BASE_URL;
      const allCategory = await Category.find();

      // Update the image URL for each category
      const updatedCategoryList = allCategory.map((category) =&amp;gt; {
        return {
          ...category._doc,
          image: `${imageBaseURL}/${category.image}`,
        };
      });

      res.status(200).json({
        message: "All Category",
        data: updatedCategoryList,
      });
    } catch (err) {
      console.log(err);
      res.status(500).json({
        code: 500,
        message: "Internal server error.",
      });
    }
  };

  //Category wise movies
  static categoryWiseMovie = async (req, res) =&amp;gt; {
    try {
      const imageBaseURL = process.env.IMAGE_BASE_URL;
      const allCategories = await Category.find();

      // Update the image URL for each category
      const updatedCategoryList = await Promise.all(allCategories.map(async (category) =&amp;gt; {
        // Find all movies related to this category
        const movies = await Movie.find({ category_id: category._id });

        // Update the image URL for each movie
        const updatedMovies = movies.map((movie) =&amp;gt; {
          return {
            ...movie._doc,
            image: `${imageBaseURL}/${movie.image}`,
          };
        });

        return {
          ...category._doc,
          image: category.image ? `${imageBaseURL}/${category.image}` : null,
          movies: updatedMovies,
        };
      }));

      res.status(200).json({
        message: "Category-wise Movies",
        data: updatedCategoryList,
      });
    } catch (err) {
      console.log(err);
      res.status(500).json({
        code: 500,
        message: "Internal server error.",
      });
    }
};

  //singel Category
  static singleCategory = async (req, res) =&amp;gt; {
    const imageBaseURL = process.env.IMAGE_BASE_URL;
    const category = req.category;
    category.image = `${imageBaseURL}/${category.image}`;
    res.status(200).json({
      message: "Single Category",
      data: category,
    });
  };

  //store category
  static store = async (req, res) =&amp;gt; {
    const { name } = req.body;
    const image = req.files.image[0].filename;

    try {
      // const categoryInfo = await new Category({
      //     name,
      //     image: image ?? ''
      // }).save()
      console.log("controller req", image);

      const categoryInfo = await Category.create({
        name,
        image: image,
      });

      res.status(200).json({
        message: "Category Create Successfully",
        data: categoryInfo,
      });
    } catch (err) {
      res.status(500).json({
        code: 500,
        message: "Internal server error.",
      });
    }
  };

  //Category update or edit
  static update = async (req, res) =&amp;gt; {
    const { name } = req.body;
    const imageBaseURL = process.env.IMAGE_BASE_URL;
    let image = null; // Initialize image as null
    let existingCategory = req.category;
    try {
      if (req.files &amp;amp;&amp;amp; req.files.image) {
        // If a new image then delete the old image
        if (existingCategory &amp;amp;&amp;amp; existingCategory.image) {
          fs.unlinkSync(`public/uploads/category/${existingCategory.image}`);
        }
        // Save the new image
        image = req.files.image[0].filename;
      }

      existingCategory.name = name ? name : existingCategory.name;
      existingCategory.image = image ? image : existingCategory.image;
      existingCategory.save();

      // Update the image URL with the base URL
      const updateCategory = await Category.findById(existingCategory._id);
      updateCategory.image = `${imageBaseURL}/${updateCategory.image}`;

      res.status(200).json({
        message: "Category updated successfully.",
        data: updateCategory,
      });
    } catch (err) {
      console.log(err);
      res.status(500).json({
        code: 500,
        message: "Internal server error.",
      });
    }
  };

  //delete category
  static delete = async (req, res) =&amp;gt; {
    try {
      // Find the category by ID
      const category = req.category;

      // Delete the category's image file if it exists
      if (category.image) {
        fs.unlinkSync(`public/uploads/category/${category.image}`);
      }

      // Delete the category from the database
      await Category.deleteOne({ _id: category._id });

      res.status(200).json({
        message: "Category deleted successfully.",
      });
    } catch (err) {
      console.log(err);
      res.status(500).json({
        code: 500,
        message: "Internal server error.",
      });
    }
  };
}

export default CategoryController;

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

&lt;/div&gt;



&lt;p&gt;Now again open your postman and test this api like this way&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%2Fudzrly97lbj3p85fzwsg.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%2Fudzrly97lbj3p85fzwsg.png" alt="Image description" width="800" height="415"&gt;&lt;/a&gt;&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%2F6dh5gzkl9py3gy3mgjgq.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%2F6dh5gzkl9py3gy3mgjgq.png" alt="Image description" width="800" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we are discussing movie route. So go to routes folder and create this-&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;movieRoute.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import express from "express";
import MovieController from "../controllers/MovieController.js";
import fileFolderName from "../middleware/fileFolderName.js";
import storage from "../middleware/fileUpload.js";
import { movieStoreValidator } from "../middleware/validation/movieStoreValidator.js";
import auth from '../middleware/auth.js';

const router = express.Router();

router.get("/all-movies", MovieController.allMovie);
router.get("/top-movies", MovieController.topMovie);
router.get("/single-movie/:movieId", MovieController.singleMovie);

  router.post(
    "/movie-store",
    //auth,
    movieStoreValidator,
    fileFolderName("movie"),
    storage.fields([{ name: "image", maxCount: 1 }]),
    MovieController.store
  );

  router.post(
    "/ai-movie-store",
    //auth,
    fileFolderName("movie"),
    storage.fields([{ name: "image", maxCount: 1 }]),
    MovieController.aiStore
  );

  router.put(
    "/movie-update/:movieId",
    //auth,
    fileFolderName("movie"),
    storage.fields([{ name: "image", maxCount: 1 }]),
    MovieController.update
  );

  router.delete(
    "/movie-delete/:movieId",
    //auth,
    MovieController.delete
  );

//   //find product by id
 router.param("movieId", MovieController.movieById);

  export default router;

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

&lt;/div&gt;



&lt;p&gt;and then go to controllers folder and create this-&lt;br&gt;
&lt;strong&gt;MovieController.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import fs from "fs";
import { v4 } from "uuid";
import Movie from '../models/Movie.js';

class MovieController{
  //find a movie by  id
  static movieById = async (req, res, next, id) =&amp;gt; {
    const movie = await Movie.findById(id);
    console.log('movie info', movie)
    if (!movie) {
      return res.status(404).json({
        code: 404,
        message: "Movie not found.",
      });
    }

    req.movie = movie;
    // console.log('cat result', req.category)
    next();
  };

  //all Movie
  static allMovie = async (req, res) =&amp;gt; {
    try {
      const imageBaseURL = process.env.IMAGE_BASE_URL;
      const allMovie = await Movie.find().populate('category_id');

      // Update the image URL for each category
      const updatedMovieList = allMovie.map((movie) =&amp;gt; {

        return {
            ...movie._doc,
            image: `${imageBaseURL}/${movie.image}`,
            category_id: {
              ...movie.category_id._doc,
              image: `${imageBaseURL}/${movie.category_id.image}`,
            },
          };
      });

      res.status(200).json({
        message: "All Movie",
        data: updatedMovieList,
      });
    } catch (err) {
      console.log(err);
      res.status(500).json({
        code: 500,
        message: "Internal server error.",
      });
    }
  };

  //Top Movie
  static topMovie = async (req, res) =&amp;gt; {
    try {
      const imageBaseURL = process.env.IMAGE_BASE_URL;
      const topMovies = await Movie.find()
        .sort({ createdAt: -1 }) 
        .populate('category_id')
        .limit(8); 

      // Update the image URL for each movie
      const updatedTopMovies = topMovies.map((movie) =&amp;gt; {
        return {
          ...movie._doc,
          image: `${imageBaseURL}/${movie.image}`,
          category_id: {
            ...movie.category_id._doc,
            image: `${imageBaseURL}/${movie.category_id.image}`,
          },
        };
      });

      res.status(200).json({
        message: "Top 8 Movies",
        data: updatedTopMovies,
      });
    } catch (err) {
      console.log(err);
      res.status(500).json({
        code: 500,
        message: "Internal server error.",
      });
    }
  };

  //singel Category
  static singleMovie = async (req, res) =&amp;gt; {
    const imageBaseURL = process.env.IMAGE_BASE_URL;
    const movie = req.movie;
    await movie.populate('category_id');
    movie.image = `${imageBaseURL}/${movie.image}`;
    movie.category_id.image = `${imageBaseURL}/${movie.category_id.image}`;
    res.status(200).json({
      message: "Single movie",
      data: movie,
    });
  };

   //store Movie
   static store = async (req, res) =&amp;gt; {
    const { title, discription, category_id } = req.body;
    const image = req.files.image[0].filename;

    try {
        const movieInfo = await Movie.create({
        title,
        discription,
        category_id,
        image: image,
      });

      res.status(200).json({
        message: "Movie Create Successfully",
        data: movieInfo,
      });
    } catch (err) {
      res.status(500).json({
        code: 500,
        message: "Internal server error.",
      });
    }
  };

  //Ai movie store
  static aiStore = async (req, res) =&amp;gt; {

    const { title, category_id, description, image } = req.body;

    console.log('node-1', req.body)


    // Convert the base64 image data to a buffer
    const imageBuffer = Buffer.from(image, 'base64');

    // Generate a unique filename for the image using UUID
    const imageName = `${v4()}.jpg`;

    try {
      // Save the image to a directory (you can change the path as needed)
      fs.writeFileSync(`./public/uploads/movie/${imageName}`, imageBuffer);

      // Save the movie information to the database
      const movieInfo = await Movie.create({
        title,
        description,
        category_id,
        image: imageName,
      });

      res.status(200).json({
        message: "Movie Create Successfully",
        data: movieInfo,
      });
    } catch (err) {
      res.status(500).json({
        code: 500,
        message: "Internal server error.",
      });
    }
  };

  //Category update or edit
  static update = async (req, res) =&amp;gt; {
    const { title, discription, category_id } = req.body;
    const imageBaseURL = process.env.IMAGE_BASE_URL;
    let image = null; // Initialize image as null
    let existingMovie = req.movie;
    try {
      if (req.files &amp;amp;&amp;amp; req.files.image) {
        // If a new image then delete the old image
        if (existingMovie &amp;amp;&amp;amp; existingMovie.image) {
          fs.unlinkSync(`public/uploads/movie/${existingMovie.image}`);
        }
        // Save the new image
        image = req.files.image[0].filename;
      }
      console.log('movie data', title, discription, category_id)
      existingMovie.title = title ? title : existingMovie.title;
      existingMovie.discription = discription ? discription : existingMovie.discription;
      existingMovie.category_id = category_id ? category_id : existingMovie.category_id;
      existingMovie.image = image ? image : existingMovie.image;
      existingMovie.save();

      console.log("existingMovie", existingMovie)
      // Update the image URL with the base URL
      const updateMovie = await Movie.findById(existingMovie._id);
      updateMovie.image = `${imageBaseURL}/${updateMovie.image}`;

      res.status(200).json({
        message: "Movie updated successfully.",
        data: updateMovie,
      });
    } catch (err) {
      console.log(err);
      res.status(500).json({
        code: 500,
        message: "Internal server error.",
      });
    }
  };

  //delete category
  static delete = async (req, res) =&amp;gt; {
    try {
      // Find the category by ID
      const movie = req.movie;

      // Delete the category's image file if it exists
      if (movie.image) {
        fs.unlinkSync(`public/uploads/movie/${movie.image}`);
      }

      // Delete the category from the database
      await movie.deleteOne({ _id: movie._id });

      res.status(200).json({
        message: "movie deleted successfully.",
      });
    } catch (err) {
      console.log(err);
      res.status(500).json({
        code: 500,
        message: "Internal server error.",
      });
    }
  };

}

export default MovieController

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

&lt;/div&gt;



&lt;p&gt;Now we do finish touch. Open postman and test it,  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%2Frxsb7cj4xv5vviw4m4w9.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%2Frxsb7cj4xv5vviw4m4w9.png" alt="Image description" width="800" height="411"&gt;&lt;/a&gt;&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%2Fzhk1eq3mdrw6ulr7kpgv.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%2Fzhk1eq3mdrw6ulr7kpgv.png" alt="Image description" width="800" height="400"&gt;&lt;/a&gt;&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%2Fqqde1cdyqdbtof1ueo5h.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%2Fqqde1cdyqdbtof1ueo5h.png" alt="Image description" width="800" height="517"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, our 1st part is done. Now we will do 2nd part&lt;br&gt;
Scaffolding redux-toolkit in NextJs. &lt;a href="https://dev.to/kamruzzaman/scaffolding-redux-toolkit-in-nextjs-1n2p"&gt;Link&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;full Project github&lt;br&gt;
&lt;strong&gt;Node&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://github.com/kamruzzamanripon/node-movie-api" rel="noopener noreferrer"&gt;https://github.com/kamruzzamanripon/node-movie-api&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;NextJs&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://github.com/kamruzzamanripon/next-movie-ui-with-node-api" rel="noopener noreferrer"&gt;https://github.com/kamruzzamanripon/next-movie-ui-with-node-api&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;NextJs UI&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://github.com/kamruzzamanripon/next-movie-ui" rel="noopener noreferrer"&gt;https://github.com/kamruzzamanripon/next-movie-ui&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>express</category>
      <category>node</category>
      <category>nextjs</category>
    </item>
    <item>
      <title>MERN Project: Movie Portal with AI- using Node &amp; Next.js</title>
      <dc:creator>syed kamruzzaman</dc:creator>
      <pubDate>Sun, 17 Dec 2023 19:39:53 +0000</pubDate>
      <link>https://dev.to/kamruzzaman/mern-project-movie-portal-with-ai-using-node-nextjs-2k7k</link>
      <guid>https://dev.to/kamruzzaman/mern-project-movie-portal-with-ai-using-node-nextjs-2k7k</guid>
      <description>&lt;p&gt;Welcome to this tutorial. In this tutorial, we are making MERN Project. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Overview of Project:&lt;/strong&gt;&lt;br&gt;
Frontend, we used NextJs and Backend used Node. This Project's main feature is, that we are using AI to make a movie portal. &lt;br&gt;
Like In Frontend, We have a form to connect Ai. We Type our idea or story in this form, and then AI will generate 3 things. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Movie Title&lt;/li&gt;
&lt;li&gt;Movie Description&lt;/li&gt;
&lt;li&gt;Title and Description wise image&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Then we saved this information in our database, like MongoDB.&lt;/p&gt;

&lt;p&gt;For doing easy our project, we separated Five parts in this project. These are&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Making API Using Node and Express. &lt;a href="https://dev.to/kamruzzaman/making-api-using-node-and-express-4a9l"&gt;Link&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Scaffolding redux-toolkit in NextJs. &lt;a href="https://dev.to/kamruzzaman/scaffolding-redux-toolkit-in-nextjs-1n2p"&gt;Link&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;API Setup in NextJs. &lt;a href="https://dev.to/kamruzzaman/api-setup-in-nextjs-3gen"&gt;Link&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;AI Prompt setup on Nextjs. &lt;a href="https://dev.to/kamruzzaman/ai-prompt-setup-on-nextjs-2109"&gt;Link&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Deploy A NextJs App and Node API on a Linux Server. &lt;a href="https://dev.to/kamruzzaman/deploy-a-nextjs-app-and-node-api-on-a-linux-server-3ge8"&gt;Link&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here this project short video and pictures.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://youtu.be/CQBIkzvocc8" rel="noopener noreferrer"&gt;Vidoe Link&lt;/a&gt; &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%2Fb1whmfravjj2an4ing96.jpg" 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%2Fb1whmfravjj2an4ing96.jpg" alt="Image description" width="800" height="513"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Form Page&lt;/strong&gt;&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%2F1mr55aflg9g42lycmw20.jpg" 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%2F1mr55aflg9g42lycmw20.jpg" alt="Image description" width="800" height="660"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;AI Result Page&lt;/strong&gt;&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%2F07hot7wo5mbp16turwvy.jpg" 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%2F07hot7wo5mbp16turwvy.jpg" alt="Image description" width="800" height="1157"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Home page&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>nextjs</category>
      <category>node</category>
      <category>mern</category>
    </item>
    <item>
      <title>Deploy a NuxtJS App and Laravel API on a Linux Server</title>
      <dc:creator>syed kamruzzaman</dc:creator>
      <pubDate>Tue, 31 Oct 2023 21:07:14 +0000</pubDate>
      <link>https://dev.to/kamruzzaman/deploy-a-nuxtjs-app-and-laravel-api-on-a-linux-server-54bh</link>
      <guid>https://dev.to/kamruzzaman/deploy-a-nuxtjs-app-and-laravel-api-on-a-linux-server-54bh</guid>
      <description>&lt;p&gt;In this tutorial, we will learn how to deploy a NuxtJS app and Laravel on a Linux server. NuxtJS will serve as the frontend view and Laravel as the backend. We have already discussed Laravel API and NuxtJS app in previous articles, which you can find here:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://dev.to/kamruzzaman/building-a-movie-portal-api-with-laravel-using-the-service-pattern-35i3"&gt;Creating the API # [Tutorial-1]&lt;/a&gt;&lt;br&gt;
&lt;a href="https://dev.to/kamruzzaman/setting-up-ai-prompt-in-nuxtjs-16e6"&gt;Configure AI Prompt # [Tutorial-2]&lt;/a&gt;&lt;br&gt;
&lt;a href="https://dev.to/kamruzzaman/laravel-api-integration-in-nuxtjs-b89"&gt;Designing the UI # [Tutorial-3]&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Linux is a popular and widely used server operating system. In this tutorial, we will be using Ubuntu 22.04.3. I assume you are familiar with Linux, so let's get started.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt; Before we begin, ensure you have the following:&lt;br&gt;
   1.A remote server (VPS)&lt;br&gt;
   2.A domain name&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1&lt;/strong&gt;: Check your VPS for the following software and versions. Install them if they are not already present.&lt;br&gt;
   1.nginx -v&lt;br&gt;
   2.php -v&lt;br&gt;
   3.mysql&lt;br&gt;
   4.composer -v&lt;br&gt;
   5.phpMyAdmin (optional)&lt;br&gt;
   6.node -v&lt;br&gt;
   7.npm -v&lt;br&gt;
   8.git --version&lt;br&gt;
   9.pm2 –version&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Connect Your Domain to Your Server&lt;/strong&gt;&lt;br&gt;
Go to your domain manager, then to the DNS Manager, and set up your IP address. First, create a sub-domain for the Laravel API.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F762f34fc5k9q2f42gp22.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%2F762f34fc5k9q2f42gp22.png" alt="Image description" width="800" height="408"&gt;&lt;/a&gt;&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%2Ftc59vdc1o2kgh4upsibs.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%2Ftc59vdc1o2kgh4upsibs.png" alt="Image description" width="800" height="578"&gt;&lt;/a&gt;&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%2Fykwwmhv5oq5v383ksy27.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%2Fykwwmhv5oq5v383ksy27.png" alt="Image description" width="800" height="387"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note: Your domain setup page may look different from this.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Then, check your DNS here: &lt;a href="https://dnschecker.org/" rel="noopener noreferrer"&gt;https://dnschecker.org/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3&lt;/strong&gt;: Upload Your Laravel and Nuxt App to GitHub&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4&lt;/strong&gt;: Server SSH Configuration&lt;br&gt;
Go to your server and check if there is an .ssh folder. If not, create one:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Now create a key for your Laravel app:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssh-keygen -f laravel-movie-api -t ed25519 -C "your_email@example.com"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should now see two files in your &lt;strong&gt;.ssh&lt;/strong&gt; folder:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;laravel-movie-api
2.laravel-movie-api.pub&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Open &lt;strong&gt;laravel-movie-api.pub&lt;/strong&gt; and copy the code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cat laravel-movie-api.pub
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, go to your GitHub and open your Laravel project. Click the "Settings" button and paste the key in the key field.&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%2Funrfglnzn4isq8j47p0h.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%2Funrfglnzn4isq8j47p0h.png" alt="Image description" width="800" height="272"&gt;&lt;/a&gt;&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%2F535tkcnxzg9oml2yd57b.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%2F535tkcnxzg9oml2yd57b.png" alt="Image description" width="800" height="357"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Back on your server, create a config file&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;touch ~/.ssh/config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and add the following code to 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;Host laravel-movie-api
        HostName github.com
        User your_github_username
        IdentityFile ~/.ssh/laravel-movie-api
        IdentitiesOnly yes

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

&lt;/div&gt;



&lt;p&gt;Check if your GitHub project connection is okay:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssh -T git@laravel-movie-api
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you see a message indicating successful authentication, the connection is okay.&lt;br&gt;
Now, go to your home directory and copy the GitHub link. &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%2F5n4gpbzxioyczwy4xkvm.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%2F5n4gpbzxioyczwy4xkvm.png" alt="Image description" width="627" height="671"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Modify this link as shown below, due to the created config file in the &lt;strong&gt;.ssh&lt;/strong&gt; folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Syntax: git clone git@HOST:GITHUB_USERNAME/REPO_NAME
Example: git clone git@laravel-movie-api:your_github_username/laravel-movie-api.git

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

&lt;/div&gt;



&lt;p&gt;Move the cloned project to the &lt;strong&gt;/var/www&lt;/strong&gt; folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo mv laravel-movie-api /var/www
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Navigate to the &lt;strong&gt;www&lt;/strong&gt; folder, then to the &lt;strong&gt;laravel-movie-api&lt;/strong&gt; folder, and execute the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cp .env.example .env 
composer install --optimize-autoloader --no-dev
npm install
php artisan key:generate

# Set Permission for storage and bootstrap/cache Folder
sudo chown -R www-data:www-data storage
sudo chown -R www-data:www-data bootstrap/cache
# Add your User and web server user to www-data group
sudo usermod -a -G www-data your_username
sudo usermod -a -G www-data nginx
# Set storage's File Permission to 644
sudo find storage -type f -exec chmod 644 {} \;
# Set storage's Folder Permission to 775
sudo find storage -type d -exec chmod 775 {} \;
Or
sudo chmod -R 775 storage/
# Create Symbolic Link at public/storage which points to the storage/app/public directory.
php artisan storage:link

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 5: Upload Your MySQL Database to the Server&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 6: Configure Nginx for Laravel&lt;/strong&gt;&lt;br&gt;
Go to the Nginx folder and create a configuration file for your Laravel app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd /etc/nginx/sites-available
sudo nano laravel-movie-api

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

&lt;/div&gt;



&lt;p&gt;Add the following configuration&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 laravel-movie-api.yourdomain.com www.laravel-movie-api.yourdomain.com;
    root /var/www/laravel-movie-api/public;
    index index.php index.html;
    location / {
         try_files $uri $uri/ /index.php$is_args$args;
    }
    location ~ \.php$ {
        fastcgi_pass unix:/run/php/php8.2-fpm.sock;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
    }
}

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

&lt;/div&gt;



&lt;p&gt;Enable the virtual host or create a symbolic link of the virtual host file:&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/laravel-movie-api /etc/nginx/sites-enabled/laravel-movie-api
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check if the configuration is correct:&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;Restart 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 service nginx restart
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 7: Check Your Sub-Domain&lt;/strong&gt;&lt;br&gt;
Open your browser and check if your sub-domain is working without errors.&lt;br&gt;
&lt;strong&gt;Step 8: Set Up Nuxt App&lt;/strong&gt;&lt;br&gt;
Go to your domain manager, then to the DNS Manager, and set up your IP address for the NuxtJS app. Use this app on your main domain. &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%2Fi7grt7nu69o337sh0ftl.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%2Fi7grt7nu69o337sh0ftl.png" alt="Image description" width="800" height="578"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then check your DNS here: &lt;a href="https://dnschecker.org/" rel="noopener noreferrer"&gt;https://dnschecker.org/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 9: Server SSH Configuration for Nuxt App&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Repeat the SSH key generation and GitHub configuration steps as done for the Laravel app, but this time for your NuxtJS app. Remember to replace the relevant names and paths.&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 -f nuxt-movie-ui-with-laravel-api -t ed25519 -C "your_email@example.com" 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;now you can see two file in your &lt;strong&gt;.ssh&lt;/strong&gt; folder&lt;br&gt;
   1.nuxt-movie-ui-with-laravel-api&lt;br&gt;
   2.nuxt-movie-ui-with-laravel-api.pub&lt;br&gt;
Now open  &lt;strong&gt;nuxt-movie-ui-with-laravel-api.pub&lt;/strong&gt; file and copy code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cat nuxt-movie-ui-with-laravel-api.pub
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then go to your github and open your Nuxt project. Click Settings button&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%2Fary19yyrn7obhsbzu3b8.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%2Fary19yyrn7obhsbzu3b8.png" alt="Image description" width="800" height="319"&gt;&lt;/a&gt;&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%2Fifk8h9ztjwxv46o3otfs.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%2Fifk8h9ztjwxv46o3otfs.png" alt="Image description" width="800" height="386"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Go to your server and open 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;Sudo nano ~/.ssh/config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and add this code into 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;Host laravel-movie-api
        HostName github.com
        User kamruzzamanripon
        IdentityFile ~/.ssh/ laravel-movie-api
        IdentitiesOnly yes

Host nuxt_movie
        HostName github.com
        User kamruzzamanripon
        IdentityFile ~/.ssh/nuxt-movie-ui-with-laravel-api
        IdentitiesOnly yes

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

&lt;/div&gt;



&lt;p&gt;Now check your github project connection is ok. Here is code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssh -T git@nuxt_movie
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now go to your Server home directory and copy github link&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%2Fnvxbh042d448qppw2e56.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%2Fnvxbh042d448qppw2e56.png" alt="Image description" width="478" height="488"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Past your terminal but don’t press enter. Suppose we got this link&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git@github.com:kamruzzamanripon/nuxt-movie-ui-with-laravel-api.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;here we modify this link because we created a config file in &lt;strong&gt;.ssh&lt;/strong&gt; folder. Here is the modified code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Syntax:- git clone git@HOST:GITHUB_USERNAME/REPO_NAME
Example:- git clone git@nuxt_movie: kamruzzamanripon/nuxt-movie-ui-with-laravel-api.git

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

&lt;/div&gt;



&lt;p&gt;Your server clones this project. Now you move this file to your &lt;strong&gt;/var/www&lt;/strong&gt; folder&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Sudo mv nuxt-movie-ui-with-laravel-api  /var/www
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Go to www/folder. And then go nuxt-movie-ui-with-laravel-api folder. Command below line&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
npm run build
sudo nano ecosystem.config.js

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;# Write below code in ecosystem.config.js file&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module.exports = {
  apps : [
      {
        name: "myapp",
        script: ".output/server/index.mjs",
        port: 3001
      }
  ]
}


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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Restart Nginx:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Start the app using pm2:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pm2 start ecosystem.config.js
pm2 save
pm2 status

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 11: Configure Nginx for Nuxt App&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Go to the Nginx folder and create a configuration file for your Nuxt app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd /etc/nginx/sites-available
sudo nano nuxt-movie-ui-with

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

&lt;/div&gt;



&lt;p&gt;Add the following configuration:&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 yourdomain.com www.yourdomain.com;
    location / {
        proxy_pass http://localhost:3001;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
}

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

&lt;/div&gt;



&lt;p&gt;Enable the virtual host or create a symbolic link of the virtual host file:&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/nuxt-movie-ui-with-laravel-api /etc/nginx/sites-enabled/nuxt-movie-ui-with-laravel-api
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check if the configuration is correct:&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;Restart 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 service nginx restart
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 12: Check Your Domain&lt;/strong&gt;&lt;br&gt;
Open your browser and check if your domain is working without errors.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 13: Update your .env file&lt;/strong&gt;&lt;br&gt;
Open your laravel-movie-api .env file&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%2Fv5ryqvc2jd24eg0rc3kk.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%2Fv5ryqvc2jd24eg0rc3kk.png" alt="Image description" width="800" height="430"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;update as require&lt;br&gt;
Now open nuxt-movie-ui-with-laravel-api .env file and update&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%2F6074eaororu36go29y5x.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%2F6074eaororu36go29y5x.png" alt="Image description" width="800" height="440"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Congratulations! You have successfully deployed a NuxtJS app and Laravel API on a Linux server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Remark on Git Cloning:&lt;/strong&gt;&lt;br&gt;
It's important to note that we used SSH for git cloning instead of HTTPS. This choice is strategic for ease of future development. Imagine you've made some changes to your project locally. With SSH, all you need to do to update your project on the server is a simple &lt;strong&gt;git push&lt;/strong&gt; from your local machine, followed by a &lt;strong&gt;git pull&lt;/strong&gt; on the server. This process updates your app with the latest changes. Using HTTPS wouldn't offer this straightforward workflow, as it would require repeating the entire process from the beginning for every update.&lt;br&gt;
Furthermore, you can streamline the process even more by implementing auto-deployment. With this setup, any update you push to GitHub automatically reflects on your server. This automation can be achieved through GitHub Actions. In a subsequent tutorial, I plan to delve into the features of GitHub Actions and how you can use them for auto-deployment.&lt;br&gt;
Stay tuned for that, and in the meantime, enjoy the benefits of easy project updates with SSH!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;All Episodes&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://dev.to/kamruzzaman/building-a-movie-portal-api-with-laravel-using-the-service-pattern-35i3"&gt;Creating the API # [Tutorial-1]&lt;/a&gt;&lt;br&gt;
&lt;a href="https://dev.to/kamruzzaman/setting-up-ai-prompt-in-nuxtjs-16e6"&gt;Configure AI Prompt # [Tutorial-2]&lt;/a&gt;&lt;br&gt;
&lt;a href="https://dev.to/kamruzzaman/laravel-api-integration-in-nuxtjs-b89"&gt;Designing the UI # [Tutorial-3]&lt;/a&gt;&lt;br&gt;
&lt;a href="https://dev.to/kamruzzaman/deploy-a-nuxtjs-app-and-laravel-api-on-a-linux-server-54bh"&gt;Setting up on an Linux Server # [Tutorial-4]&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ubuntu</category>
      <category>javascript</category>
      <category>laravel</category>
      <category>vue</category>
    </item>
    <item>
      <title>Laravel API Integration in Nuxt.js</title>
      <dc:creator>syed kamruzzaman</dc:creator>
      <pubDate>Tue, 31 Oct 2023 21:07:06 +0000</pubDate>
      <link>https://dev.to/kamruzzaman/laravel-api-integration-in-nuxtjs-b89</link>
      <guid>https://dev.to/kamruzzaman/laravel-api-integration-in-nuxtjs-b89</guid>
      <description>&lt;p&gt;In this tutorial, we'll integrate a Laravel API into a Nuxt.js application. Let's dive in!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Set Up Environment File&lt;/strong&gt;&lt;br&gt;
First, set up your environment file as shown in the screenshot below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;OPEN_AI_API_KEY=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
API_BASE_URL=http://127.0.0.1:8000/api/
API_ROOT_URL=http://127.0.0.1:8000
VITE_API_URL=http://127.0.0.1:8000/api/

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 2: Set Up Axios&lt;/strong&gt;&lt;br&gt;
While there are different ways to set up Axios, in this tutorial, we'll use it as a helper function. Create a folder named helpers, and inside it, create a file named axios.js. Type the configuration as shown in the block: &lt;/p&gt;

&lt;p&gt;We've already set up the necessary packages like Axios and Pinia. &lt;strong&gt;If you haven't done this yet, follow the instructions in the link below&lt;/strong&gt;: &lt;br&gt;
&lt;a href="https://dev.to/kamruzzaman/setting-up-ai-prompt-in-nuxtjs-16e6"&gt;Configure AI Prompt : Part-2&lt;/a&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 axios from 'axios';

const axiosInstance = axios.create({
  baseURL: import.meta.env.VITE_API_URL, 
  headers: {
    'Content-Type': 'application/json',
  },
});

axiosInstance.interceptors.request.use(function (config) {
  // Do something before request is sent
  let token = localStorage.getItem("token");
  config.headers["Authorization"] = "Bearer " + token;
  return config;
});

export default axiosInstance;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 3: Set Up Pinia Store&lt;/strong&gt;&lt;br&gt;
Create the following files in your Pinia store:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;aiMovieStore.js&lt;/li&gt;
&lt;li&gt;categoryStore.js&lt;/li&gt;
&lt;li&gt;userStore.js&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now, add code to each file as shown in the block below:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;userStore.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { defineStore } from 'pinia';
import axios from '../helpers/axios.js';


export const userStore = defineStore('userStore', {
  state: () =&amp;gt; ({
    loading: false,
    logInUserInfo: {},
    categories: [],
    isLogIn:false,
  }),

  getters: {
    authCheck() {
      if (process.client) {
        if (this.isLogIn == true) {
           return true;
        }
        if(this.isLogIn == false){
          const token = localStorage.getItem('token');
          return !!token;
        }

        return false;
      }
    },
    token (){
      if (typeof window == undefined) {
        return false;
      }
      const token = localStorage.getItem("token") ?? this.logInUserInfo.data.token
      if(token){
        return token;
      }

      return null;
    }
  },

  actions: {
     async actionLogin(payload, token) {
      try {
        const response = await axios.post('/login', payload);
        this.logInUserInfo = response.data;
        this.isLogIn = true;
        // Save the user data and token in local storage (for page reload)
        localStorage.setItem('user', JSON.stringify(response.data.data));
        localStorage.setItem('token', response.data.data.token);
        navigateTo("/");
      } catch (error) {
        throw new Error('Login failed.', error);
      }
    },

    async actionLogout(payload) {
      const response = await axios.post('/logout');
      localStorage.removeItem('user');
      localStorage.removeItem('token');
      this.logInUserInfo = null;
      this.isLogIn = false;
    },

    async actionRegister(payload){
      console.log('registation', payload)
      try {
        const response = await axios.post('/register', payload);
        navigateTo("/login");
      } catch (error) {
        throw new Error('Registration failed.', error);
      }
    }





  }
});

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;# categoryStore.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { defineStore } from 'pinia';
import { ref } from 'vue';
import axios from "../helpers/axios.js";

export const categoryStore = defineStore('categoryStore', () =&amp;gt; {
  const categories = ref([])

  const actionStoreCategory = async(payload)=&amp;gt;{
    console.log('actionStoreCategory', payload)
    const formData = new FormData();
    formData.append("name", payload.name);
    formData.append("image", payload.file);
    //console.log("actionManualMovieDataSendToServer", [...formData]);
    const response = await axios.post("/category-store", formData, {
      headers: {
        "Content-Type": "multipart/form-data",
      },
    });
    navigateTo("/");
  }

  const actionAllCategoryApi = async()=&amp;gt; {
    const config = useRuntimeConfig();
    const data = await axios.get("/all-category");
    console.log("axios data", data);
    categories.value = data.data.data;
    //this.actionAiMovieData = movieData;
  }

    return { actionStoreCategory, actionAllCategoryApi, categories }
  })
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;# aiMovieStore.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import axios from "../helpers/axios.js";

import { defineStore } from "pinia";

//define pinia store
export const aiMovieStore = defineStore("aiMovieStore", {

  //initial store
  state: () =&amp;gt; ({
    loading: false,
    aiMovieData: {},
    categories: [],
    topMovies: [],
    categoryWiseMovie: [],
  }),

  getters: {},

  actions: {
    async getToken() {
      return await axios.get("/sanctum/csrf-cookie");
    },

    //here payload is ai data. this data store in pinia
    async actionAiMovieData(payload) {
      this.aiMovieData = payload;
      this.loading = false;
    },
    async actionAllCategoryApi() {
      const config = useRuntimeConfig();
      const data = await axios.get("/all-category");
      console.log("axios data", data);
      this.categories = data.data.data;
      //this.actionAiMovieData = movieData;
    },

    //here send ai data to server for save this data in our database
    async actionAiMovieDataSendServer(payload) {
      console.log("actionAiMovieDataSendServer", payload);
      const response = await axios.post("/ai-movie-store", payload);
      navigateTo("/");
    },

    //here menual movie data send to server for save this data in our database
    async actionManualMovieDataSendToServer(payload) {
      console.log("actionManualMovieDataSendToServer", payload);
      const formData = new FormData();
      formData.append("title", payload.title);
      formData.append("description", payload.description);
      formData.append("category_id", payload.category);
      //formData.append('image', payload.file??"")
      if (payload.file) {
        formData.append("image", payload.file);
      }
      console.log("actionManualMovieDataSendToServer", [...formData]);
      const response = await axios.post("/movie-store", formData, {
        headers: {
          "Content-Type": "multipart/form-data",
        },
      });
      navigateTo("/");
    },

    //fetch top movies from database
    async actionTopMovie(payload) {
      const data = await axios.get("/top-movies");
      this.topMovies = data.data.data.data;
    },

    //fetch category wise movie list from database
    async actionCategoryWiseMovie() {
      const data = await axios.get("/category-wise-movies");
      console.log("actionCategoryWiseMovie", data);
      this.categoryWiseMovie = data.data.data.data;
    },
  },
});

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 4: Set Up App Pages&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Go to the &lt;strong&gt;pages&lt;/strong&gt; folder. You'll find the following pages&lt;/p&gt;

&lt;p&gt;1.index.vue&lt;br&gt;
2.login.vue&lt;br&gt;
3.registration.vue&lt;br&gt;
4.manual-make-movie.vue&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;index.vue&lt;/strong&gt;&lt;br&gt;
This page includes three components:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;HeroSection&lt;/li&gt;
&lt;li&gt;TopMovies&lt;/li&gt;
&lt;li&gt;CategoryWiseMovies&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In the &lt;strong&gt;TopMovies&lt;/strong&gt; component, add the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;template&amp;gt;
&amp;lt;section class="mt-9 bg-lime-300 dark:bg-rose-500 p-5 rounded-md"&amp;gt;
    &amp;lt;div class="flex items-center justify-between"&amp;gt;
        &amp;lt;span class="font-semibold text-gray-700 text-base dark:text-white"&amp;gt;Top Movies&amp;lt;/span&amp;gt;
        &amp;lt;div class="flex items-center space-x-2 fill-gray-500"&amp;gt;
            &amp;lt;NavigationArrow /&amp;gt;
        &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;

    &amp;lt;div class="mt-4 grid grid-cols-2  sm:grid-cols-4 gap-x-5 gap-y-5"&amp;gt;
        &amp;lt;div class="flex flex-col rounded-xl overflow-hidden aspect-square border dark:border-zinc-600" v-for="topMovie in aiMOvieStoreInfo.topMovies" :key="topMovie"&amp;gt;
            &amp;lt;img :src="topMovie.image" class=" h-4/5 object-cover w-full  " alt=""&amp;gt;
            &amp;lt;div class="w-full h-1/5 bg-white dark:bg-zinc-800 dark:text-white px-3 flex items-center justify-between border-t-2 border-t-red-600"&amp;gt;
                &amp;lt;span class="capitalize  font-medium truncate"&amp;gt;{{ topMovie.title }}&amp;lt;/span&amp;gt;
                &amp;lt;div class="flex space-x-2 items-center text-xs"&amp;gt;
                    &amp;lt;IconImdbLogo /&amp;gt;
                    &amp;lt;span&amp;gt;{{ getRandomRating(topMovie.id) }}&amp;lt;/span&amp;gt;
                &amp;lt;/div&amp;gt;
            &amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/section&amp;gt;
&amp;lt;/template&amp;gt;

&amp;lt;script setup&amp;gt;
import { aiMovieStore } from '@/store/aiMovieStore.js';
import IconImdbLogo from '../Icon/ImdbLogo.vue';
import NavigationArrow from '../Icon/NavigationArrow.vue';

const aiMOvieStoreInfo = aiMovieStore();
const randomRating = ref((Math.random() * 4 + 5).toFixed(1));
watchEffect(()=&amp;gt;{
    aiMOvieStoreInfo.actionTopMovie();
},[])
const getRandomRating = (id) =&amp;gt; {
  const hashValue = id % 1000; // Use a large enough number for uniqueness, adjust as needed
  const baseRating = (hashValue % 20 + 75) / 10; // Random number between 7.5 and 9.5
  const randomRating = parseFloat((Math.random() * (10 - baseRating) + baseRating).toFixed(1));

  return randomRating &amp;gt; 10 ? 10 : randomRating;
};

&amp;lt;/script&amp;gt;

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

&lt;/div&gt;



&lt;p&gt;For the &lt;strong&gt;CategoryWiseMovies&lt;/strong&gt; component, add 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;template&amp;gt;
&amp;lt;section 
    class="mt-9 p-5 rounded-md" 
    v-for="category in aiMOvieStoreInfo.categoryWiseMovie" 
    :key="category"
    :class="getRandomColorClass()"
&amp;gt;
    &amp;lt;div class="flex items-center justify-between"&amp;gt;
        &amp;lt;span class="font-semibold text-gray-700 text-base dark:text-white"&amp;gt;{{ category.name }}&amp;lt;/span&amp;gt;
        &amp;lt;div class="flex items-center space-x-2 fill-gray-500"&amp;gt;
            &amp;lt;NavigationArrow /&amp;gt;
        &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;

    &amp;lt;div class="mt-4 grid grid-cols-2 gap-y-5 sm:grid-cols-3 gap-x-5 "&amp;gt;
        &amp;lt;div class="flex flex-col rounded-xl overflow-hidden aspect-square border dark:border-zinc-600" v-for="movie in getRandomMovies(category.movies)" :key="movie"&amp;gt;
            &amp;lt;img :src="getImageUrl(movie.image)" class=" h-4/5 object-cover w-full  " alt=""&amp;gt;
            &amp;lt;div class="w-full h-1/5 bg-white dark:bg-zinc-800 dark:text-white px-3 flex items-center justify-between border-t-2 border-t-red-600"&amp;gt;
                &amp;lt;span class="capitalize  font-medium truncate"&amp;gt;{{ movie.title }}&amp;lt;/span&amp;gt;
                &amp;lt;div class="flex space-x-2 items-center text-xs"&amp;gt;
                    &amp;lt;IconImdbLogo /&amp;gt;
                    &amp;lt;span&amp;gt;7.4&amp;lt;/span&amp;gt;
                &amp;lt;/div&amp;gt;
            &amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/section&amp;gt;
&amp;lt;/template&amp;gt;

&amp;lt;script setup&amp;gt;
import { aiMovieStore } from '@/store/aiMovieStore';
import IconImdbLogo from '../Icon/ImdbLogo.vue';
import NavigationArrow from '../Icon/NavigationArrow.vue';
const config = useRuntimeConfig();
const imageRootUrl = config.public.API_ROOT_URL

const aiMOvieStoreInfo = aiMovieStore();
onMounted(()=&amp;gt;{
    aiMOvieStoreInfo.actionCategoryWiseMovie()
})

// For make random color
const getRandomColorClass = () =&amp;gt; {
  const randomIndex = Math.floor(Math.random() * colors.length);
  return colors[randomIndex];
};
const colors = [
  'bg-red-400',
  'bg-blue-400',
  'bg-green-400',
  'bg-yellow-400',
  'bg-pink-400',
  'bg-blue-800',
  'bg-black',

];
//image generat url
const getImageUrl = (thumbnail) =&amp;gt; {
  const imageUrl = thumbnail ? thumbnail.replace('public', 'storage') : '';
  return `${imageRootUrl}/${imageUrl}`;
};

//random 3 movies generate
const getRandomMovies = (movies) =&amp;gt; {
  if (movies.length &amp;lt;= 3) {
    return movies;
  } else {
    const shuffledMovies = [...movies].sort(() =&amp;gt; Math.random() - 0.5);
    return shuffledMovies.slice(0, 3);
  }
};
&amp;lt;/script&amp;gt;

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

&lt;/div&gt;



&lt;p&gt;With that, we've completed the home page, which should look 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%2Fwoywy66x9w2afpltvr4g.jpg" 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%2Fwoywy66x9w2afpltvr4g.jpg" alt="Image description" width="800" height="1477"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;# registration.vue Page&lt;/strong&gt;&lt;br&gt;
Add the following lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;template&amp;gt;
    &amp;lt;div class="flex h-screen items-center justify-center bg-gray-100"&amp;gt;
      &amp;lt;div class="bg-white p-8 shadow-md rounded-lg w-80"&amp;gt;
        &amp;lt;h1 class="text-2xl font-semibold mb-4"&amp;gt;Register&amp;lt;/h1&amp;gt;
        &amp;lt;form @submit.prevent="register"&amp;gt;
          &amp;lt;div class="mb-4"&amp;gt;
            &amp;lt;label class="block text-sm font-medium text-gray-700"&amp;gt;Name&amp;lt;/label&amp;gt;
            &amp;lt;input v-model="userInfo.name" type="text" class="mt-1 block w-full border rounded-md px-3 py-2" required /&amp;gt;
          &amp;lt;/div&amp;gt;
          &amp;lt;div class="mb-4"&amp;gt;
            &amp;lt;label class="block text-sm font-medium text-gray-700"&amp;gt;Email&amp;lt;/label&amp;gt;
            &amp;lt;input v-model="userInfo.email" type="email" class="mt-1 block w-full border rounded-md px-3 py-2" required /&amp;gt;
          &amp;lt;/div&amp;gt;
          &amp;lt;div class="mb-4"&amp;gt;
            &amp;lt;label class="block text-sm font-medium text-gray-700"&amp;gt;Password&amp;lt;/label&amp;gt;
            &amp;lt;input v-model="userInfo.password" type="password" class="mt-1 block w-full border rounded-md px-3 py-2" required /&amp;gt;
          &amp;lt;/div&amp;gt;
          &amp;lt;div class="mb-4"&amp;gt;
            &amp;lt;label class="block text-sm font-medium text-gray-700"&amp;gt;Confirm Password&amp;lt;/label&amp;gt;
            &amp;lt;input v-model="userInfo.password_confirmation" type="password" class="mt-1 block w-full border rounded-md px-3 py-2" required /&amp;gt;
          &amp;lt;/div&amp;gt;
          &amp;lt;button type="submit" class="bg-blue-500 text-white py-2 px-4 rounded hover:bg-blue-600"&amp;gt;Register&amp;lt;/button&amp;gt;
        &amp;lt;/form&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/template&amp;gt;

  &amp;lt;script setup&amp;gt;
  import { userStore } from '@/store/userStore.js';
import { ref } from 'vue';

  const userInfo = ref({
    name:"",
    email:"",
    password:"",
    password_confirmation:"",
  })
  const userStoreInfo = userStore()

  const register = async ()=&amp;gt;{
    if(userInfo.value.password != userInfo.value.password_confirmation){
      alert('Password does not match, please check' );
      return;
    }

    await userStoreInfo.actionRegister(userInfo.value)

  }

  &amp;lt;/script&amp;gt;

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

&lt;/div&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%2Fy52ywqfj66nnhze5xnfv.jpg" 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%2Fy52ywqfj66nnhze5xnfv.jpg" alt="Image description" width="800" height="382"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;# login.vue page&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;template&amp;gt;
    &amp;lt;div class="flex h-screen items-center justify-center bg-gray-100"&amp;gt;
      &amp;lt;div class="bg-white p-8 shadow-md rounded-lg w-80"&amp;gt;
        &amp;lt;h1 class="text-2xl font-semibold mb-4"&amp;gt;Login &amp;lt;/h1&amp;gt;
        &amp;lt;form @submit.prevent="login"&amp;gt;
          &amp;lt;div class="mb-4"&amp;gt;
            &amp;lt;label class="block text-sm font-medium text-gray-700"&amp;gt;Email&amp;lt;/label&amp;gt;
            &amp;lt;input v-model="loginInfo.email" type="email" class="mt-1 block w-full border rounded-md px-3 py-2 text-red-800" required /&amp;gt;
          &amp;lt;/div&amp;gt;
          &amp;lt;div class="mb-4"&amp;gt;
            &amp;lt;label class="block text-sm font-medium text-gray-700"&amp;gt;Password&amp;lt;/label&amp;gt;
            &amp;lt;input v-model="loginInfo.password" type="password" class="mt-1 block w-full border rounded-md px-3 py-2 text-red-800" required /&amp;gt;
          &amp;lt;/div&amp;gt;
          &amp;lt;button type="submit" class="bg-blue-500 text-white py-2 px-4 rounded hover:bg-blue-600"&amp;gt;Login&amp;lt;/button&amp;gt;
        &amp;lt;/form&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/template&amp;gt;

  &amp;lt;script setup&amp;gt;
 import { ref } from 'vue';
import { userStore } from '../store/userStore.js';

 const userStoreInfo = userStore();
 const loginInfo = ref({
    email:'',
    password:''
 })

 const login = async ()=&amp;gt;{

    if(!loginInfo.value.email || !loginInfo.value.password){
        alert('Please Type input field')
    }

    await userStoreInfo.actionLogin(loginInfo.value,)

 }
  &amp;lt;/script&amp;gt;

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

&lt;/div&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%2F7xd3k1jd8p3xprgtbzm2.jpg" 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%2F7xd3k1jd8p3xprgtbzm2.jpg" alt="Image description" width="800" height="387"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;# manual-make-movie.vue&lt;/strong&gt;&lt;br&gt;
In this page, navigate to the FormInput component and add the following line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;template&amp;gt;
    &amp;lt;div class="bg-gray-200 p-5 rounded-md dark:bg-black"&amp;gt;

        &amp;lt;div class="text-center mb-8 relative"&amp;gt;
            &amp;lt;h1 class="text-2xl font-bold text-gray-700 mb-3 dark:text-white"&amp;gt;Manual Movie Maker&amp;lt;/h1&amp;gt;
            &amp;lt;img src="/assets/pictures/storytelling-08.gif" alt="" class="rounded-full w-48 h-48 absolute -top-5 right-0 sm::hidden"&amp;gt;
        &amp;lt;/div&amp;gt;

        &amp;lt;div class="mx-10 px-10 py-16 bg-gray-400 dark:bg-black dark:border rounded-md"&amp;gt;
            &amp;lt;div class="mb-6"&amp;gt;
                &amp;lt;label for="large-input" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white"&amp;gt;Movie
                    Title
                &amp;lt;/label&amp;gt;
                &amp;lt;input type="text" id="large-input"
                    class="block w-full p-4 text-gray-900 border border-gray-300 rounded-lg bg-gray-50 sm:text-md focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
                    placeholder="Type your Movie Title..." v-model="movieData.title"&amp;gt;
                &amp;lt;p v-if="!movieData.title &amp;amp;&amp;amp; isSubmitted" class="text-red-500 mt-2"&amp;gt;Movie Title is required.&amp;lt;/p&amp;gt;
            &amp;lt;/div&amp;gt;
            &amp;lt;div class="mb-6"&amp;gt;
                &amp;lt;label for="base-input" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white"&amp;gt;Movie
                    Category&amp;lt;/label&amp;gt;
                &amp;lt;select 
                    class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
                    v-model="movieData.category"
                    &amp;gt;
                    &amp;lt;option value=""&amp;gt;Choose category&amp;lt;/option&amp;gt;
                    &amp;lt;option :value="category.id" v-for="category in aiMovieStoreInfo.categories" :key="category"&amp;gt;
                        {{ category.name }}
                    &amp;lt;/option&amp;gt;
                &amp;lt;/select&amp;gt;
                &amp;lt;p v-if="!movieData.category &amp;amp;&amp;amp; isSubmitted" class="text-red-500 mt-2"&amp;gt;Movie Category is required.&amp;lt;/p&amp;gt;
            &amp;lt;/div&amp;gt;
            &amp;lt;div class="mb-6"&amp;gt;
                &amp;lt;label for="message" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white"&amp;gt;Movie Short
                    Description&amp;lt;/label&amp;gt;
                &amp;lt;textarea id="message" rows="4"
                    class="block p-2.5 w-full text-sm text-gray-900 bg-gray-50 rounded-lg border border-gray-300 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
                    placeholder="Type Movie short description..." v-model="movieData.description"&amp;gt;&amp;lt;/textarea&amp;gt;
                &amp;lt;p v-if="!movieData.description &amp;amp;&amp;amp; isSubmitted" class="text-red-500 mt-2"&amp;gt;Movie Description is required.&amp;lt;/p&amp;gt;
            &amp;lt;/div&amp;gt;
            &amp;lt;div class="mb-6"&amp;gt;
                &amp;lt;label for="large-input" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white"&amp;gt;
                    Select Movie Poster
                &amp;lt;/label&amp;gt;
                &amp;lt;input 
                    type="file" id="large-input"
                    class="block w-full p-4 text-gray-900 border border-gray-300 rounded-lg bg-gray-50 sm:text-md focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
                    placeholder="Type your Movie Title..."
                    @change="handleFileChange"
                &amp;gt;
                &amp;lt;p v-if="!movieData.file &amp;amp;&amp;amp; isSubmitted" class="text-red-500 mt-2"&amp;gt;Movie Poster is required.&amp;lt;/p&amp;gt;
            &amp;lt;/div&amp;gt;
            &amp;lt;div class="text-right"&amp;gt;
                &amp;lt;button type="submit" class="bg-black text-white p-3 rounded-md dark:border" @click="submitForm"&amp;gt;Make
                    Movie
                &amp;lt;/button&amp;gt;
            &amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;

    &amp;lt;/div&amp;gt;
&amp;lt;/template&amp;gt;

&amp;lt;script setup&amp;gt;
import { ref } from 'vue';
import { aiMovieStore } from '../../store/aiMovieStore.js';

const movieData = ref({
    title: "",
    category: "",
    description: "",
    file:""
})

const aiMovieStoreInfo = aiMovieStore();
const isSubmitted = ref(false);

onMounted(()=&amp;gt;{
    aiMovieStoreInfo.actionAllCategoryApi()
})

//input file handler
function handleFileChange(event) {
  const file = event.target.files[0];
  movieData.value.file = file;
}
//validation input
function validateInputs() {
    const { title, category, description, file } = movieData.value;
    if (!title || !category || !description || !file) {
        //alert('Please fillup the form')
        return false;
    }
    return true;
}

const submitForm = () =&amp;gt; {
    isSubmitted.value = true;
    if (validateInputs()) {
        aiMovieStoreInfo.actionManualMovieDataSendToServer(movieData.value)
    }
};


&amp;lt;/script&amp;gt;

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

&lt;/div&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%2Fwne6xf8cwyt8cajf0078.jpg" 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%2Fwne6xf8cwyt8cajf0078.jpg" alt="Image description" width="800" height="437"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With that, our API integration is complete. The next step is to deploy this app on our Ubuntu server. &lt;strong&gt;Here's the tutorial link for that&lt;/strong&gt;: &lt;br&gt;
[link]&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Here is github link of this project&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://github.com/kamruzzamanripon/nuxt-movie-ui-with-laravel-api" rel="noopener noreferrer"&gt;https://github.com/kamruzzamanripon/nuxt-movie-ui-with-laravel-api&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;All Episodes&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://dev.to/kamruzzaman/building-a-movie-portal-api-with-laravel-using-the-service-pattern-35i3"&gt;Creating the API # [Tutorial-1]&lt;/a&gt;&lt;br&gt;
&lt;a href="https://dev.to/kamruzzaman/setting-up-ai-prompt-in-nuxtjs-16e6"&gt;Configure AI Prompt # [Tutorial-2]&lt;/a&gt;&lt;br&gt;
&lt;a href="https://dev.to/kamruzzaman/laravel-api-integration-in-nuxtjs-b89"&gt;Designing the UI # [Tutorial-3]&lt;/a&gt;&lt;br&gt;
&lt;a href="https://dev.to/kamruzzaman/deploy-a-nuxtjs-app-and-laravel-api-on-a-linux-server-54bh"&gt;Setting up on an Linux Server # [Tutorial-4]&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's all. Happy Learning :) .&lt;br&gt;
[if it is helpful, giving a star to the repository 😇]&lt;/p&gt;

</description>
      <category>ai</category>
      <category>nuxt</category>
      <category>laravelapi</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
