realtime data streaming using server-sent events(sse) with react.js and node.js
Real-time data streaming is essential for keeping users instantly informed of events. Traditional cl...
We live in a world where real-time data streaming has become paramount. Real-time data streaming has become a necessity in modern applications because it keeps users notified immediately an event happens. But most of the communication we see on the internet involves a client application making a request to the server which in turn processes the request and send back response to the client. This takes time to process and there are scenarios where a server needs to send data to the client without the client necessarily initiating a request. !!! success Sponsored <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 css-x82yov" style="--Paper-shadow:0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)"><p class="MuiTypography-root MuiTypography-body1 css-fyswvn">Checkout this affordable amazon products for amazing shopping experience</p><a title="Amazon Movers & Shakers" target="_blank" href="https://amzn.to/3Akqx6j">Amazon Movers & Shakers</a></div> !!! This could be done using long polling, websockets, webhooks or server-sent events. Examples of real-time applications include; instant messaging, notification system, online gaming, chat apps, videoconferencing, data streaming, sport updates, stock prices e.t.c. But our main focus in the article is Server-sent events. **Video Tutorial** _If you prefer to watch and learn an in-depth tutorial on how to implement server-sent events(SSEs) with react js and node js, here is a full video for you._ _Please don't forget to like, comment, subscribe to my youtube channel and share the video with your friends._ <iframe width="560" height="315" src="https://www.youtube.com/embed/d06PFSHfdzM?si=JDWFqN4IJ-ygMHVy" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> ## Different techniques for client-server communication Below are some of the techniques used for client server communication **Polling** is a technique where the application repeatedly polls data from the server and if you are familiar HTTP protocol, it involves request/response format. It is a traditional technique used by the vast majority of AJAX applications. The trade off with polling is that it creates greater HTTP overhead. !!! abstract Sponsored <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 css-x82yov" style="--Paper-shadow:0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)"><p class="MuiTypography-root MuiTypography-body1 css-fyswvn">Looking for the best coding and programming devices, check out this affordable products on amazon</p><a title="Amazon Movers & Shakers in Computers & Accessories" target="_blank" href="https://amzn.to/48qJocy">Amazon Movers & Shakers in Computers & Accessories</a></div> !!! **Long polling** is a technique in which if the server does not have the data available when a request is made from the client, the server holds the request open until data is available. The server responds when data becomes available, closes the connection and when the client receives the new data, it sends another request to the server again. This cycle is repeated endlessly until either of them closes the connection. The major drawback of this mechanism is once the server has sent the data; it cannot send further data until a new poll request arrives. **WebSockets** is a communication protocol that provides full-duplex bi-directional, communication channel over a single TCP connection. This mechanism creates a two-way connection between the server and the client i.e the server can send data to the client and client can send data to the server as well This is great for things like chat apps, instant messaging e.t.c. However, sometimes you need some updates from the server without waiting for the client to repeatedly initiate requests. This includes; friends' online status updates, newsfeeds e.t.c **Server-Sent Events** is an HTTP standard that enables a client application to automatically receive updates or event streams from the server once an initial connection has been established. It’s a server push technology that allows client apps to receive data transmission from the server via an HTTP connection and describes how servers can stream data to the client once an initial connection has been established. Server-sent events (SSEs) are unidirectional in nature i.e., only the server can push updates to client. SSE is commonly used to send automatic updates or continuous data streams to a browser client. The main difference between Server-Sent Events and long-polling is that SSEs are handled directly by the browser and the client app simply has to listen for messages. SSE contained in the JavaScript EventSource API in order to open a connection to the server to continue receiving event streams. In server-sent events, automatic updates are sent to client rather than pulled from the client. !!! warning Sponsored <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 css-x82yov" style="--Paper-shadow:0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)"><p class="MuiTypography-root MuiTypography-body1 css-fyswvn">Are you a movie enthusiast, this amazon collections will wow you. Try it out!.</p><a title="Amazon Movers & Shakers" target="_blank" href="https://amzn.to/3UtxeKg">Amazon Movers & Shakers</a></div> !!! ## Server-sent events VS Websockets **WebSockets** provide **bi-directional**, full-duplex communication. It creates a two-way channel where the client can send data to the server and the server can also send data to client. This enables a real-time communication in both directions. This makes it effective for cases like real-time chat apps, games etc. However, there are some scenarios where client apps don’t need to send data to server but only consumes from the server and this is where server-sent events(SSEs) comes in. In SSEs, the communication is **unidirectional** i.e., the server continuously pushed event streams to the client once an initial connection has been established. Examples include; real-time notification systems, sport updates, stock prices, status updates, newsfeed, cryptocurrency updates e.t.c **Server-sent Events implementation** Server sent server can be implemented both server side and client-side environment. **Client-side API** The SSE client API is contained in the **EventSource** object. When using SSE, the browser will generate an instance of **EventSource** first to initiate a connection to the server. In order to detect if a browser supports SSEs, use the code snippet below; ``` const url = "http://localhost:5000/stream" //url can be your server url if ('EventSource' in window) { let source = new EventSource(url) } ``` !!! info Sponsored <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 css-x82yov" style="--Paper-shadow:0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)"><p class="MuiTypography-root MuiTypography-body1 css-fyswvn">Get the latest cell phones and must-have accessories on Amazon! With top brands, exclusive deals, and fast delivery, it’s never been easier to stay connected and stylish. Find your perfect tech match today!</p><a title="Amazon Movers & Shakers in Cell Phones & Accessories" target="_blank" href="https://amzn.to/4fnDf3g">Amazon Movers & Shakers in Cell Phones & Accessories</a></div> !!! **Note:** The **URL** above can be in the same domain as the current **URL** of the application or it can be cross domain as well. When the URL passed to the **EventSource** constructor is an absolute URL, its origin (scheme, domain, port) must match that of the server. When a cross-domain is passed as the url, you can specify a second _options _ parameter with **withCredentials** property to indicate whether to send the cookie & auth headers altogether or not as shown below. ``` const url = "http://localhost:5000/stream" //url is your server url if ('EventSource' in window) { let source = new EventSource(url, {withCredentials: true}) } ``` **Eventsource object events** By default, there are three (3) events which include **message**, **open** and **error** to listen on. - The **open** event indicates a successful connection between the server and the client. - The **error** event handles an error connection between the server and the client. - The **message** event is used to listen on live stream data emitted by the server after a successful connection. SSEs are flexible enough that you can even define your own custom events on the server which you in turn listen on, on the client side. Below are the three (3) default event listeners with their callbacks. ``` source.addEventListener('message', function(e) { console.log(e.data); }, false); ``` ``` source.addEventListener('open', function(e) { // successful connection. }, false); ``` ``` source.addEventListener('error', function(e) { // error occurred }, false); ``` **EventSource object properties** Some of the properties of the **EventSource** instance include; - **readyState** e.g source.readyState - readyState value of 0 indicates connecting - readyState value of 1 indicates open - readyState value of 0 indicates closed - **url** e.g source.url returns connection url - **withCredentials** e.g source.withCredentials show whether or not **withCredentials** is true. **EventSource object methods** The **closed()** method can be called to close the connection e.g source.closed() **Server-side implementation** **SSE Data format** The SSE data sent by the server to the browser must be UTF-8 encoded text with the following HTTP header. ``` Content-Type: text/event-stream Cache-Control: no-cache Connection: keep-alive ``` The information sent each time consists of several messages, and each message is separated by **\n\n**. Each message is composed of several lines of code internally, and each line should be written as follows. [field]: value\n The above field can take the following four values. - **data ** indicates the payload to be sent. - **retry** indicates the reconnection time in seconds and it's optional - **event** can be a custom event e.g notification defaults to **message** when no event is passed - **id** indicates the id of the data to be sent and it's optional ``` const emitSSE= (res, id, data) =>{ res.write('id: ' + id + '\n'); res.write("data: " + data + '\n\n'); res.flush() } const handleSSE = (req, res) =>{ res.writeHead(200, { 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache', 'Connection': 'keep-alive' }); const id = (new Date()).toLocaleTimeString(); // Sends a SSE every 3 seconds on a single connection. setInterval(function() { emitSSE(res, id, (new Date()).toLocaleTimeString()); }, 3000); emitSSE(res, id, (new Date()).toLocaleTimeString()); } //use it app.get("/stream", handleSSE) ``` **Using Server-sent events with React.js and Node.js** Implementing server-sent events can be fairly simple but it gets confusing when you want target or send an event to a specific user as there is no clear way to exchange user data with the server. But in the video tutorial below; we have addressed the issues of sending global events as well as targeting specific users. In the video tutorial below, we are going to build and deploy a realtime twitter-like newsfeed using server-sent events(SSE) with react.js, node.js and mongodb from the scratch and deploy it on cpanel. This tutorial is for beginners and advanced programmers who wish to learn to implement the following; 1. How to implement SSE in react js and node js application 2. How to broadcast data to all users using server-sent events 3. How to send data to a specific or single user using server-sent events 4. How to implement LIKE button 5. API(Application Programming Interface) 6. React Hooks(useState, useContext, useReducer) 7. Hosting(Deployment) on cpanel **Resources & Demo** > [Get the code on github here](https://github.com/torver213/react-node-sse) **Summary** _Realtime data streaming has become a necessity in a standard modern application as this keeps your user notified of all the activities within your application. In this article, we discussed various techniques of client server communication and the need to go with server-sent events. Server-sent events(SSE) is a server push technology that enables a client to receive live stream updates from the server via a HTTP connection. It is lightweight and supported by most modern browsers and as a result, it's well suited for real-time automatic data stream from the server_ !!! attention Sponsored <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 css-x82yov" style="--Paper-shadow:0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)"><p class="MuiTypography-root MuiTypography-body1 css-fyswvn">Upgrade your wardrobe with ease on Amazon! Discover the latest styles, unbeatable deals, and fast shipping—all from the comfort of home. Find your perfect fit today!</p><a title="Amazon Movers & Shakers" target="_blank" href="https://amzn.to/3C8QhDu">Amazon Movers & Shakers</a></div> !!! **Video Tutorial** If you want to watch and learn an in-depth tutorial on how to implement server-sent events(SSEs) with react js and node js, here is a video for you. _Please don't forget to like, comment, subscribe to my youtube channel and share the video with your friends._ <iframe width="560" height="315" src="https://www.youtube.com/embed/d06PFSHfdzM?si=JDWFqN4IJ-ygMHVy" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
how to host your next.js website on cpanel using namecheap shared hosting
Hosting a Next.js website on cPanel with Namecheap's shared hosting is a cost-effective alternative to platforms like Vercel. By exporting your Next.j...
**How to Host Your Next.js Website on cPanel Using Namecheap Shared Hosting** In this article, we'll guide you through the complete process of hosting your Next.js website on cPanel with Namecheap's shared hosting. If you’re familiar with Next.js, you might think it can only be hosted on Vercel or other dedicated platforms, but with a few adjustments, you can easily deploy it on cPanel. This approach is perfect if you already have a hosting package and want to avoid additional costs. **Why Host Next.js on cPanel?** Hosting Next.js on cPanel, particularly with a service like Namecheap’s shared hosting, can be surprisingly efficient and cost-effective. Shared hosting packages allow you to leverage your existing subscription without paying extra fees per team member or enduring recurring costs. This can be particularly appealing for small to medium projects where the full serverless capabilities of Next.js may not be critical. !!! info Sponsored <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 css-x82yov" style="--Paper-shadow:0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)"><p class="MuiTypography-root MuiTypography-body1 css-fyswvn">Looking for quality books to read? Try amazon books today!</p><a title="Amazon Movers & Shakers in Books" target="_blank" href="https://amzn.to/3NNJpOi">Amazon Movers & Shakers in Books</a></div> !!! ### Step-by-Step Guide 1. **Setup the Development Environment** - Start by creating your Next.js project locally using `npx create-next-app` or `yarn create next-app`, then develop and test your site to ensure it’s ready for production. 2. **Prepare for Static Export** - Run `next build && next export` to prepare your Next.js app for static hosting, which generates a static version of your site in the `out` directory. 3. **Upload Files to cPanel** - In your cPanel dashboard, go to the **File Manager** and upload the contents of your `out` directory to the `public_html` directory. You can use an FTP client like FileZilla to streamline this process. 4. **Set Up Your Domain** - Link your domain to the public folder. If Namecheap hosts your domain, make sure your DNS settings point to the correct server IP associated with your cPanel hosting. 5. **Verify and Test** - Visit your domain in the browser to ensure your static site is loading as expected. !!! hint Sponsored <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 css-x82yov" style="--Paper-shadow:0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)"><p class="MuiTypography-root MuiTypography-body1 css-fyswvn">Looking for the best platform to monetize your online content?</p><a title="Try Monetize Today" target="_blank" href="https://monetag.com/?ref_id=uawc">Try Monetize Today</a></div> !!! ### Pros of Hosting Next.js on cPanel - **Cost Savings**: With shared hosting, you only pay once for a hosting plan, avoiding extra charges for additional team members or frequent renewals. - **Flexible Next.js Features**: You retain access to core Next.js features like optimized image handling, static file serving, and custom routing. - **Control Over Hosting**: You have complete access to your site files and hosting settings, giving you more control over backup, customizations, and optimizations. ### Cons of Hosting Next.js on cPanel - **No Serverless Functions**: Shared hosting doesn’t support serverless functions natively, limiting some Next.js dynamic functionalities. - **No Automatic Static Optimization**: Next.js automatic optimization only fully functions with platforms that support server rendering, so static exports may not be as optimized as they would be on Vercel or a dedicated Next.js hosting. ### Alternatives for More Dynamic Sites If your site relies heavily on serverless functions or server-side rendering, consider adding a backend service or using a hybrid deployment approach. Some possible solutions include: 1. **Using API Gateways**: You can link to external APIs hosted on platforms that support serverless functions, such as AWS or DigitalOcean. 2. **Vercel Hybrid Setup**: For projects that only require serverless functions occasionally, a hybrid approach of hosting static pages on cPanel and dynamic functions on Vercel can also work. ### Final Thoughts Hosting your Next.js site on cPanel is a practical choice for static sites or those with minimal server-side requirements, offering substantial cost savings. Follow these steps, and you can have your Next.js site up and running on your existing shared hosting plan. !!! abstract Sponsored <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 css-x82yov" style="--Paper-shadow:0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)"><p class="MuiTypography-root MuiTypography-body1 css-fyswvn">Looking for the best platform to purchase electronics?</p><a title="Try Amazon Electronics Today!" target="_blank" href="https://amzn.to/4e6ndty">Try Amazon Electronics Today!</a></div> !!! ### Video For a step by step tutorial on how to host next.js website on cpanel using namecheap shared hosting, please watch the youtube video below. There are a lot of things you will learn. _We run this youtube channel known as Codesermon where We publish amazing tech content. Please don't forget to like, comment, subscribe and turn on notification for more awesome videos like this. Thank you._ <iframe width="560" height="315" src="https://www.youtube.com/embed/lex3qZAf_Ok?si=hFvw_MLDmnMVHzBf" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
how to host client react.js application on cpanel
Hosting a React.js app on cPanel is a cost-effective and straightforward option that utilizes existing shared hosting plans, avoiding extra fees. By s...
In order to host your react.js app on cpanel, we will assume you have acquired a hosting package with cpanel accessible. In this article, we will be using namecheap shared hosting package but you can use any hosting plan. **Video Tutorial** If you are the visual type like me, go ahead and watch the video below. _Please don't forget to like, share, comment, subscribe and turn on notification as that will give me the motivation to do more awesome videos and tutorials like this._ <iframe width="560" height="315" src="https://www.youtube.com/embed/F0ORxJWZ_D8?si=HeiE4lHvOzfprA1c" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> ## Things to note before hosting your react.js app - Ensure your domain is linked to your hosting account. - If main domain is already in use, create a subdomain dedicated for this project. In this article we will be using **https://supablog.supatechie.ga** but go ahead and replace it with your domain or subdomain. Once you’ve all these ready, follow the instructions below; - Create a new directory called project on your desktop or in your drive. - If you don’t have a react.js app already, go ahead and open your command line prompt and navigate to the project directory and run ``` npx create-react-app@latest client ``` The above command will create a new react.js app with name client for you but if you already have one, go ahead and skip this step. - After the **client** app has been created, open the **project** directory in any code editor of your choice. - Within the **client** directory, open **public** directory and create a new file with the name **.htaccess** and copy & paste the configuration below and save your file. !!! attention Sponsored <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 css-x82yov" style="--Paper-shadow:0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)"><p class="MuiTypography-root MuiTypography-body1 css-fyswvn">Looking for affordable home appliances? Search no more</p><a title="Buy on Amazon Now" target="_blank" href="https://amzn.to/3YHqgUy">Buy on Amazon Now</a></div> !!! ``` <IfModule mod_rewrite.c> RewriteEngine On RewriteBase / RewriteRule ^index\.html$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-l RewriteRule . /index.html [L] </IfModule> ``` - Still within your **client** directory, open **package.json** file and add _“homepage”: “your_domain_url”_ key value pair, e.g ``` "name": "supablog", "version": "0.1.0", "private": true, "homepage": "https://supablog.supatechie.ga", ``` Save all the changes you have made. - Open your cmd and navigate to your **client** directory and run the command below to prepare the app for production. ```bash npm run build ``` - Once it’s done building assuming no error occurred, open your file explorer on your system and go to **project/client** directory and you should see **build** directory. Open the build directory and highlight all the directories and files and zip it. If you are on windows, you can simply install **WinRAR** in order to zip your files. - Next step is to open your browser and login to your cpanel, scroll to _Files _ section and click on **File Manager**. This will take you to the files directory. ![Cpanel File Manager](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9huym0965sqdd3tjlz5v.png) - If you’re using your main domain, go ahead and open **public_html** to host your app but if you created a subdomain, cpanel should automatically create a new empty directory with name of the subdomain for you in this case our directory will be called **supablog.supatechie.ga** ![File Manager supablog.supatechie.ga](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3452axbh8kogoh3nkpwo.png) - Open the directory and click on **upload ** at the top navigation bar ![cpanel upload button](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7o5no6vif7cm54nyulyj.png) - This should take you to an upload page. Click on the select file and it should open your system’s file explorer for you. Navigate to your _project/cliecnt/build/_ and select the **build.zip** file. ![cpanel upload files](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j9lhparx3zy8gzekik9y.png) - Once the zip file is uploaded, click on the link below to go back to your cpanel File Manager. - You will locate the **build.zip** over there, select the file and click on extract file on the top right. Your files will be extracted successfully - Open a new browser tab and type your domain name and the site should be opened successfully !!! note Sponsored <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 css-x82yov" style="--Paper-shadow:0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)"><p class="MuiTypography-root MuiTypography-body1 css-fyswvn">Looking for a platform to easily monetize your content?</p><a title="Try monetize today!" target="_blank" href="https://monetag.com/?ref_id=uawc">Try monetize today!</a></div> !!! Congratulations if you have made it this far. Now you have successfully hosted your react.js app on cpanel without losing any functionality. P.S _If you want a full tutorial on how to build a react.js and node.js express RESTful API from the scratch and host it on cpanel, please follow this my playlist on Youtube thank you._ <iframe width="560" height="315" src="https://www.youtube.com/embed/F0ORxJWZ_D8?si=HeiE4lHvOzfprA1c" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
improve the performance of a node js application server side by using simple techniques
To improve the performance of a Node.js application server, use compression to reduce data transfer size and caching to store frequently accessed data...
You have worked on that awesome looking node.js app but maybe your app experiencing slow performance and you have been thinking of ways to improve the performance of your application. Luckily for you, in this tutorial we’re going to see how we can improve the performance of a node js application by using these ubiquitous techniques. There are many ways you can improve the performance of your node.js application but in this tutorial, we will be focusing on compression and cache-manager. ## Compression Compression helps by reducing amount of response data from Nodejs application before sending it down to client application for consumption. This greatly improves the performance of application and as a result it takes a shorter time for a client application to receive the response as the amount of the response payload is drastically reduced. In our Nodejs application, we can easily make use of compression by installing it from npm ``` npm install compression ``` and passing it as a middleware to our express app. The compression library supports different compression formats like Gzip, deflate with Gzip being the default. Example of using compression in our Node.js express app is shown below; ``` const compression = require("compression"); const express = require("express"); const app = express(); // this will compress all responses app.use(compression()) ``` !!! success Sponsored <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 css-x82yov" style="--Paper-shadow:0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)"><a title="Try Monetag" target="_blank" href="https://chikraighotoops.com/4/8313667"><div class="MuiBox-root css-0"><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh">Looking for the best platform to monitize your content?</p><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh">Try Monetag</p></div></a></div> !!! ## Caching Caching is the process of storing frequently accessed data in a temporary storage. Caching is a great way to improve the performance of an application as temporary cached data can be retrieved quicker which reduces bandwidth and database reads. If an application has higher number of users, there is need to cache data that can be frequently accessed by your users. Caching can be done server side and client side but, in this article, we will be focusing on server-side caching only. There are many libraries available when it comes to caching under node js such as cache-manager, redis cache, memcacahed, node-cache e.t.c but we will be using cache-manager to implement the server-side caching. ### Benefits of using cache-manager Cache-manager comes with a lot of benefits which include; - It includes a wrap function that lets you wrap any function in cache. - It features a built-in memory cache (using node-lru-cache), with the standard functions you'd expect in most caches; set, get, mset, mget, del - It lets you set up a tiered cache strategy. This may be of limited use in most cases, but imagine a scenario where you expect tons of traffic, and don't want to hit your primary cache (like Redis) for every request. You decide to store the most commonly-requested data in an in-memory cache, perhaps with a very short timeout and/or a small data size limit. - It allows you to get and set multiple keys at once for caching store that support it. This means that when getting muliple keys it will go through the different caches starting from the highest priority one (see multi store below) and merge the values it finds at each level. > [Read more about cache-manager here](https://www.npmjs.com/package/cache-manager) ### Basic implementation of cache-manager In order to implement cache manager, you have to install the package from npm using the command ```bash npm install cache-manager ``` ```javascript const cacheManager = require('cache-manager'); const memoryCache = cacheManager.caching({store: 'memory', max: 100, ttl: 10/*seconds*/}); var ttl = 5; // Note: callback is optional in set() and del(). // Note: memory cache clones values before setting them unless // shouldCloneBeforeSet is set to false memoryCache.set('foo', 'bar', {ttl: ttl}, function(err) { if (err) { throw err; } memoryCache.get('foo', function(err, result) { console.log(result); // >> 'bar' memoryCache.del('foo', function(err) {}); }); }); function getUser(id, cb) { setTimeout(function () { console.log("Returning user from slow database."); cb(null, {id: id, name: 'Bob'}); }, 100); } var userId = 123; var key = 'user_' + userId; // Note: ttl is optional in wrap() memoryCache.wrap(key, function (cb) { getUser(userId, cb); }, {ttl: ttl}, function (err, user) { console.log(user); // Second time fetches user from memoryCache memoryCache.wrap(key, function (cb) { getUser(userId, cb); }, function (err, user) { console.log(user); }); }); // Outputs: // Returning user from slow database. // { id: 123, name: 'Bob' } // { id: 123, name: 'Bob' } ``` In order to implement our full node.js express API caching system using cache-manager, you can watch the video tutorial below. In the video below(see at the bottom), I talked about compression and the full implementation of our cache system. ### What you will learn; - Why it is important to compress our server response - How to efficiently implement a cache-system to improving your node.js application performance. - How to improve the performance of your node.js application without the need for redis db. !!! abstract Sponsored <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 css-x82yov" style="--Paper-shadow:0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)"><a title="Try Amazon Online Store Today" target="_blank" href="https://amzn.to/4f8MN26"><div class="MuiBox-root css-0"><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh">Looking for the best platform to shop affordable products?</p><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh">Try Amazon Online Store Today</p></div></a></div> !!! ## Conclusion Performance of our software applications greatly determine the user retention of our application as slow performing apps will tend to drive users away. When designing a software application, extra measures like performance optimization should be put in place in order to ensure our applications perform up to expectation. In this article, you’ve learned how to improve the performance of your node.js application without necessarily paying for high costly services redis db. Although performance optimization is a broad topic and even on the node.js server-side performance optimization, there are still other factors to take into consideration as this article focused more on compression and caching. So, you can do your research on how to efficiently optimize your node.js application besides these techniques we have demonstrated here. <iframe width="560" height="315" src="https://www.youtube.com/embed/FVfgXEjG-jE?si=YnjHV9C-9Pg710E8" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> _We run this youtube channel [Codesermon](https://www.youtube.com/@codesermon) where we publish amazing tech content. Please don't forget to like, comment, subscribe and turn on notification for more awesome videos like this. Thank you._
secure nodejs rest api by limiting access to api calls using express rate limit
Securing a Node.js REST API can be achieved by using Express Rate Limit to restrict the number of API calls a client can make within a specific timefr...
# **Introduction** Have you ever been hit with the message **“login error you have reached maximum retry, please try again later?”** Yes. So many times, most especially when you have forgotten your password and have tried too many times. Well, this serves as one of the security measures for limiting brute force attacks. This could be implemented on a login page, registration page, forgot password page or reset password or the whole application. You can as well limit access to certain API endpoints until after some time. If you are a regular internet surfer, you could be wondering how you can be able to access the same site with another browser or device but couldn’t access it that particular device until after the stipulated time. Well, you are not alone, I was once in your shoes until I learnt why. In this article, we will talk about various techniques of rate limiting and we will implement an auth example using react js, node js and express framework. Grab a cup of coffee or bottle of water, let’s take a spin. # **In-depth Video Tutorial** If you want to watch the full implementation with more detailed explanation, watch the video below; <iframe width="560" height="315" src="https://www.youtube.com/embed/bxxfe9431z8?si=QUkwTiIY3zEM_Kys" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> # **What is rate limiting?** Rate limiting is a policy that allows you to control the number of requests made by a user to access backend APIs and it secures your APIs against malicious attacks like brute force. It prevents the user from making unwanted requests to backend API resources. Rate limiting gives the developer the power to control how many requests a server can handle from a user at a given period of time and if the requests exceed the maximum allowed requests, subsequent requests are spoofed. When you are developing a software application, it’s a good idea to follow security best practices to reduce the risk of hacking or malicious attacks. It is recommended that you implement rate limit on authentication endpoints such as login attempts, registration page, reset and forgot password pages in order to track and limit the number of times someone can attempt to access this endpoint. This significantly reduces a hacker’s chance of trying to guess your password using a brute force attack. !!! abstract Sponsored <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 css-x82yov" style="--Paper-shadow:0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)"><a title="Try Amazon Store Today" target="_blank" href="https://amzn.to/4fpZlSy"><div class="MuiBox-root css-0"><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh">Looking for the best place to shop at affordable rate?</p><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh">Shop on Amazon Store Today!</p></div></a></div> !!! Rating limiting is not limited to authentication endpoints only. In fact, most API offering companies use this technique to limit user API calls. This could let them track the number of times a user accesses a particular endpoint using an API given a particular period of time so as to enforce billing. As a developer you could also, enforce rate limited on any resource as the power is in your hands. ## Rate limiting constraints Rate limiting can be implemented by the following constraints; - User IP address - User location - User id or user device id or user API key ## Different Algorithms for implementing rate limiting I won’t do justice to this article if I don’t talk about different algorithms involve in designing a rate limiting system. Below is a brief summary of each algorithm with links to read more. 1. **Fixed Window Counters** This is undoubtedly the simplest technique for implementing rate limiting. In this technique, we track the number of requests made in a fixed-size time window. If the number of requests in any time window exceeds the defined ration, further requests from that client for the remainder of that window are blocked. On subsequent requests, the counter is checked to see if the defined limit is not exceeded in a given window, then process the request and increment the counter else drop the request. Clients will have to wait till the window time frame is expired before making any successful request. For instance, a client can only be allowed to make 10 requests in 30 min window time frame. If the requests are exhausted, so long as the time is not yet expired, subsequent requests will be blocked until after the time expires and another time frame will start counting on subsequent requests. 2. **Sliding Window Logs** The sliding logs technique keeps log of the timestamps for each user’s requests. This can be simply implemented with Redis or HashMap and may be sorted based on time in order to improve operations. Let’s assume a 1-minute (60 sec) rate limiting window. - Remove all the requests older than 1 minute leaving just the requests made in the current minute - Check if the requests in the current minute exceed the limit. If yes drop the request else process the request and log it - Update sorted set TTL with each update so that it’s cleaned up after being idle for some time. This technique is much more efficient than the fixed window counter but it consumes more memory. !!! quote Sponsored <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 css-x82yov" style="--Paper-shadow:0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)"><a title="Try This Best Deals on Amazon Devices & Accessories!" target="_blank" href="https://amzn.to/4fl1wXE"><div class="MuiBox-root css-0"><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh">Elevate your experience with amazing savings on Amazon devices and accessories! Shop now to find the perfect tech to enhance your daily life!</p><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh">Try This Best Deals on Amazon Devices & Accessories!</p></div></a></div> !!! 3. **Sliding Window Counters** This mechanism tries to fix the inefficiencies of both sliding window logs and fixed window counters by splitting the rate-limit window into smaller windows and track counters across those smaller windows instead of logging all the requests. For instance, instead of maintaining counters across a one-minute window, we can use one-second windows (so 60 sub-windows for a minute interval). To determine whether to process or drop a request, we take the sum of the counters of all previous 60 sub-windows from the current time. 4. **Token Bucket** In token bucket algorithm, each user receives a certain number of tokens which are periodically updated based on the timestamp. When a user makes the first request, a log is created based on the constraints above and a number of tokens specified. On subsequent requests, the log is retrieved to check if the total tokens assigned to that specific user is not exhausted then process the request and deduct a token else reject & throw an error. 5. **Leaky bucket** The leaky bucket algorithm keeps a finite number of requests for a given user in a queue manner and execute them at a constant rate. It uses queue to enforce the limit based on the queue size in a first-in first-out (FIFO) approach. Requests are taken out of the queue and processed at a constant rate. If the requests exceed the queue size, those incoming requests will be dropped until the requests in the bucket are process. It works at a constant rate no matter the amount of traffic that a server receives. For instance, if the limit is 5 requests per minute, then the queue would only be able to hold 5 requests per time. For an in-depth discussion on all the techniques, checkout the links below - [Introduction Rate Limiting](https://blog.logrocket.com/rate-limiting-node-js/) - [Rate limiting techniques](https://vikas-kumar.medium.com/rate-limiting-techniques-245c3a5e9cad) !!! warning Sponsored <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 css-x82yov" style="--Paper-shadow:0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)"><a title="Amazing Deals on Affordable Devices!" target="_blank" href="https://amzn.to/4fop7qZ"><div class="MuiBox-root css-0"><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh">Shop unbeatable prices on the latest tech and essentials at Amazon. Upgrade your life without breaking the bank—discover your perfect deal today!</p><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh">Checkout Amazing Deals on Affordable Devices!</p></div></a></div> !!! ## Implementing Rate Limit in react js, node js and express API ### Server-side implementation on Node.js and express.js To implement rate limiting on a node js express js server, we will make use of a third-party library known as express-rate-limit which has done most of the heavy lifting for us. Express-rate-limit is a basic rate-limiting middleware for Express. It limits repeated requests to public APIs and/or endpoints such as authentication routes. Boot up your cmd and navigate to your server directory, set up a basic express server and install the following dependency ```bash npm install express-rate-limit ``` - Firstly, create a directory under the server directory known as middleware - Create a file known as index.js inside the middleware directory - Copy and paste the following code. ```javascript const rateLimit = require('express-rate-limit'); const loginRateLimiter = rateLimit({ windowMs: 15 * 60 * 1000, // 15 min in milliseconds max: 5, message: ‘Login error, you have reached maximum retries. Please try again after 30 minutes', statusCode: 429 headers: true, }); module.exports = { loginRateLimiter } ``` **windowMs:** The time frame for which requests are checked/remembered. Also used in the Retry-After header when the limit is reached. **max:** The maximum number of connections to allow during the window before rate limiting the client. **message:** The response body to send back when a client is rate limited. It can be string, json, or any other value that Express's response.send method supports. **statusCode:** The HTTP status code to send back when a client is rate limited. This is just the basic configuration; you can find more about this library here [Express-rate-limit](https://www.npmjs.com/package/express-rate-limit ) !!! abstract Sponsored <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 css-x82yov" style="--Paper-shadow:0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)"><a title="Try Monetag Today!" target="_blank" href="https://chikraighotoops.com/4/8313667"><div class="MuiBox-root css-0"><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh">Looking for the best platform to monetize your content?</p><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh">Try Monetag Today!</p></div></a></div> !!! There are different ways you can use express-rate-limit within our application as shown below; **1. Using globally across all routes** If you want to use it globally, open your main server file where you have configured your express app and import the **loginRateLimiter** middleware function from middleware as shown below; ```javascript const { loginRateLimiter } = require(“./middleware”) app.use(loginRateLimiter) app.get(“/api/login, (req, res) =>{ const {username, password} = req.body const CORRECT_PWD = “1234” const CORRECT_USER = “demo” if(username.toLowerCase() === CORRECT_USER && password === CORRECT_PWD){ return res.send(“Login successful”) } return res.send(“Wrong login credentials”) }) ``` Open your postman or CURL and try to make wrong or correct requests up to 5 times and the sixth time, you will receive an error response from our **loginRateLimiter** middleware like **‘Login error, you have reached maximum retries. Please try again after 15 minutes’** The above implementation is how we use express-rate-limit globally but we might have a problem as not all routes are login routes and what if we have more than rate limit middle to apply based on different routes? That’s where per route basis comes in. !!! attention Sponsored <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 css-x82yov" style="--Paper-shadow:0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)"><a title="Incredible Deals on Amazon Electronics!" target="_blank" href="https://amzn.to/4ecMAtq"><div class="MuiBox-root css-0"><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh">Checkout this unbeatable prices on top electronics at Amazon! Upgrade your tech game without the hefty price tag—shop now for amazing savings!</p><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh">Try This Incredible Deals on Amazon Electronics!</p></div></a></div> !!! **2. Using express-rate-limit on a specific route** Copy the code below and replace the code above, you will notice on the login routes that we applied the **loginRateLimiter ** on the login route instead of using it globally on all endpoints. With this approach we can use as many different rate limiters as we want in our application. ```javascript const { loginRateLimiter } = require(“middleware”) //app.use(loginRateLimiter) app.get(“/api/login, loginRateLimiter, (req, res) =>{ const {username, password} = req.body const CORRECT_PWD = “1234” const CORRECT_USER = “demo” if(username.toLowerCase() === CORRECT_USER && password === CORRECT_PWD){ return res.send(“Login successful”) } return res.send(“Wrong login credentials”) }) ``` Open your postman or CURL and try to make wrong or correct requests up to 5 times and the sixth time, you will receive an error response from our **loginRateLimiter** middleware like **‘Login error, you have reached maximum retries. Please try again after 15 minutes’** Everything will still work like before. Hey, I want to keep this article very simple but at the same time I don’t want to compromise the implementation. I’m sorry for taking your time, lets handle just the client app in react js. I promise this is the last part as we’re done with server-side implementation. **Client-side implementation with react js** For the client-side implementation with react js where I have developed a login form and limit access to 5 requests per 15 min window size, you can get the repo here; [Get the whole repo both client & server on Gthub repo](https://github.com/supatechie/react_node_rate_limiter) _Continue reading;_ > _Please, don’t forget to also like, comment, share, subscribe to our Youtube channel and turn on notification. This will make me happy. Thank You in advance. PS._ **Summary** _Security is very paramount in every application and API calls are expensive. Rate limiting is a policy that helps protect your APIs and services from excessive use either from bad actors trying to intentionally abuse your server API service by limiting the number of requests your server API in a given duration of time. This tutorial discusses different techniques used to implement rate limiting on API endpoints as well as the need to do so. In this article, we implemented a simple login page with rate limiter forbidding a user to make further requests until the window fixed size is expired. Rate limiting if done properly can serve as one of the security measures by reducing the number of brute force attacks well as prevent overflooding your server with unnecessary requests. I demonstrated how it can be implemented in a real-life application but you can build a robust rate limiting feature for your app’s need using redisdb which makes it faster to read and write data._ !!! hint Sponsored <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 css-x82yov" style="--Paper-shadow:0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)"><a title="Try Amazon Smart Savings on Home Appliances!" target="_blank" href="https://amzn.to/3YNGlbj"><div class="MuiBox-root css-0"><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh">Transform your home with affordable appliances from Amazon! Discover great deals on essentials that make life easier—shop now and save big!</p><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh">Try Amazon Smart Savings on Home Appliances!</p></div></a></div> !!! **In-depth Video Tutorial** If you want to watch the full implementation with more detailed explanation, watch the video below; <iframe width="560" height="315" src="https://www.youtube.com/embed/bxxfe9431z8?si=QUkwTiIY3zEM_Kys" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> **Source Code** To access the source code, click on the link below; > [Click here to get Rate Limiting code](https://github.com/torver213/react_node_rate_limiter)
deploy tailwindcss, nextjs app on cpanel
Hosting your Next.js app on cPanel can be a practical solution, especially for smaller projects or personal sites. While it might lack some advanced f...
In this article I'm going to show you a step by step process on how to build and deploy your tailwindcss, nodejs & nextjs website on cpanel using namcheap shared hosting package. If you're familiar with next js, you could actually deploy your web app using a custom server other than vercel. Well, in this article I will show you how to build and deploy your tailwindcss, next.js website or app from scratch on Cpanel. !!! abstract Sponsored <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 css-x82yov" style="--Paper-shadow:0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)"><a title="Try Amazon Online Store Today!" target="_blank" href="https://amzn.to/3UyBesQ"><div class="MuiBox-root css-0"><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh">Looking for the best online shopping platform to shop at affordable rate?</p><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh">Try Amazon Online Store Today!</p></div></a></div> !!! ## Pros of hosting next.js website on cpanel **- Cost-Effective:** A one-time payment for your cPanel subscription without recurring fees per user. **Full Control:** You have more control over your hosting environment compared to serverless options. **Familiar Environment:** If you're already using cPanel for other sites, managing everything from one dashboard is convenient. ## Cons of hosting next.js website on cpanel - **No Serverless Functions:** If your application relies on serverless features, cPanel won't support them. - **Limited Scalability:** Shared hosting can limit your app's performance under heavy traffic. - **Manual Setup:** You may need to handle updates, monitoring, and maintenance manually. !!! success Sponsored <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 css-x82yov" style="--Paper-shadow:0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)"><a title="Shop the Best Tech Today!" target="_blank" href="https://amzn.to/48OhOX7"><div class="MuiBox-root css-0"><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh">Upgrade your setup with Amazon's unbeatable selection of computer devices. From laptops to peripherals, find high-quality tech at amazing prices, all just a click away!</p><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh">Shop the Best Tech Today!</p></div></a></div> !!! ## Summary Hosting your Next.js app on cPanel can be a practical solution, especially for smaller projects or personal sites. While it might lack some advanced features like serverless functions and automatic static optimization, it offers a cost-effective way to maintain control over your application. For a comprehensive visual guide, watching a YouTube tutorial can further clarify the deployment process and provide additional tips for optimizing your Next.js and Tailwind CSS applications. <iframe width="560" height="315" src="https://www.youtube.com/embed/KUBADQ3qhmE?si=DiWhrSzZHRyIlxe-" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> _Please don't forget to like, comment, subscribe and turn on notification for more awesome videos like this. Thank you._
auto deploy reactjs application on cpanel using github actions(ci/cd)
Setting up auto-deployment of your React.js app on cPanel using GitHub Actions brings efficiency and consistency to your development workflow. While t...
Setting up an automated deployment pipeline for your React.js application can save time and reduce the risk of human error when updating your live site. By leveraging GitHub Actions, you can establish a Continuous Integration and Continuous Deployment (CI/CD) workflow that pushes changes from GitHub to your cPanel-hosted application automatically. !!! info Sponsored <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 css-x82yov" style="--Paper-shadow:0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)"><a title="Checkout this unbeatable devices on Amazon" target="_blank" href="https://amzn.to/4efvtaq"><div class="MuiBox-root css-0"><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh">Looking for affordable devices and electronics to upgrade your tech space?</p><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh">Checkout this unbeatable devices on Amazon</p></div></a></div> !!! #### Prerequisites - **A GitHub Repository**: Your React.js application should be hosted on GitHub. - **cPanel Hosting Package**: Ensure your hosting plan supports Node.js or has access to SSH and a terminal. - **FTP/SFTP Credentials**: You’ll need your FTP/SFTP login details from your cPanel to set up the deployment process. #### Overview of the Process 1. **Create a GitHub Action Workflow**: Set up a YAML file to define the deployment pipeline. 2. **Connect GitHub to Your cPanel**: Use FTP or SFTP to transfer files securely. 3. **Configure cPanel for React.js**: Ensure the environment is ready to serve the built React.js files. 4. **Automate Deployment**: Every code change triggers GitHub Actions to build and deploy the app to cPanel. !!! abstract Sponsored <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 css-x82yov" style="--Paper-shadow:0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)"><a title="Try Amazon Devices & Accessories Today" target="_blank" href="https://amzn.to/4f7q9HH"><div class="MuiBox-root css-0"><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh">Discover the best of smart living with Amazon Devices & Accessories. From enhancing your home with Alexa-powered smart speakers and displays to optimizing your entertainment with Fire TV and Kindle e-readers, Amazon’s devices offer convenience, innovation, and seamless integration into your daily life. </p><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh">Try Amazon Devices & Accessories Today</p></div></a></div> !!! ### Step-by-Step Guide #### Step 1: Prepare Your React.js Application Ensure your React.js app is ready for deployment. This typically includes: - Having a production build script (`npm run build`). - Verifying all dependencies are up to date. #### Step 2: Set Up Your cPanel 1. **Create a Directory**: Log into your cPanel and navigate to the `public_html` folder or a subdirectory where you want your React app to be hosted. 2. **FTP/SFTP Credentials**: Obtain your FTP/SFTP credentials from cPanel (e.g., username, password, server address, and port). #### Step 3: Create a GitHub Actions Workflow 1. **Add a `.github/workflows/deploy.yml` File**: Create a `deploy.yml` file inside your GitHub repository to define the workflow. Here’s an example configuration: ```yaml on: push: branches: - main name: 🚀 Deploy website on push jobs: web-deploy: name: 🎉 Deploy runs-on: ubuntu-latest steps: - name: 🚚 Get latest code uses: actions/checkout@v3 - name: Use Node.js 16 uses: actions/setup-node@v2 with: node-version: '16' - name: 🔨 Build Project run: | npm install npm run build - name: 📂 Sync files uses: SamKirkland/FTP-Deploy-Action@v4.3.4 with: server: ${{ secrets.GIT_CPANEL_REACT_SERVER }} username: ${{ secrets.GIT_CPANEL_REACT_USER }} password: ${{ secrets.GIT_CPANEL_REACT_PWD }} protocol: ${{ secrets.GIT_CPANEL_REACT_PROTOCOL }} local-dir: ./build/ ``` > If you want to learn how to configure the above variables in github, there's a video at the end of this tutorial for a comprehensive step by step on how to accomplish that. 2. **Add Secrets to GitHub**: - Go to your GitHub repository settings. - Navigate to **Secrets and Variables** > **Actions**. - Add `GIT_CPANEL_REACT_SERVER`, `GIT_CPANEL_REACT_USER`, `GIT_CPANEL_REACT_PWD`, `GIT_CPANEL_REACT_PROTOCOL` as secrets with their respective values. #### Step 4: Trigger Your Workflow Once the workflow file is pushed to your repository, any changes pushed to the `main` branch will trigger the workflow. This will: - Checkout your code. - Install dependencies. - Build your React.js application. - Deploy the `build` folder to your cPanel using FTP. #### Step 5: Verify Your Deployment Navigate to your domain or subdomain to verify the deployment. Your React.js application should be live, reflecting the latest changes from GitHub. > [Click here for the full source code](https://github.com/torver213/youtube-react-cpanel) ### Benefits of This CI/CD Setup - **Automation**: Saves time by automatically deploying code on push, eliminating manual file transfers. - **Consistency**: Ensures the same build process every time, reducing deployment errors. - **Easy Updates**: Any code changes pushed to the branch will be reflected on the server automatically. ### Potential Challenges - **FTP/SFTP Security**: Ensure that your credentials are kept secure using GitHub Secrets. - **cPanel Limitations**: Shared hosting might have restrictions compared to cloud-based solutions. !!! abstract Sponsored <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 css-x82yov" style="--Paper-shadow:0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)"><a title="Try amazon computer devices today" target="_blank" href="https://amzn.to/40tIpX2"><div class="MuiBox-root css-0"><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh">Looking for the best coding laptops?</p><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh">Try amazon computer devices today</p></div></a></div> !!! ### Conclusion Setting up auto-deployment of your React.js app on cPanel using GitHub Actions brings efficiency and consistency to your development workflow. While this solution is ideal for smaller-scale applications or projects on a budget, for larger projects, consider alternatives like dedicated cloud platforms for enhanced performance and scalability. #### Bonus: Watch the Video Tutorial If you're someone who prefers a visual walkthrough, check out the video below for a step-by-step guide: <iframe width="560" height="315" src="https://www.youtube.com/embed/x_GZpOGyJpg?si=4XZqxFGMqjuQALtN" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> Don't forget to like, comment, and subscribe for more tutorials!
nextjs 14 app router authentication & role-based authorization using nextauth & mongodb adapter
This comprehensive guide provides developers with the knowledge and skills to implement secure user authentication and role-based authorization in Nex...
**Unlock the Potential of NextJS 14: Mastering NextAuth & MongoDB for Secure Authentication and Role-Based Authorization** In the dynamic realm of web development, security and user authentication are paramount. NextJS 14, a popular React framework, has emerged as a powerful tool for building secure and scalable web applications. With NextAuth and MongoDB, developers can seamlessly integrate user authentication and role-based authorization into their NextJS applications, ensuring a secure and personalized user experience. !!! abstract Sponsored <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 css-x82yov" style="--Paper-shadow:0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)"><a title="Try amazon devices today!" target="_blank" href="https://amzn.to/4eiEQX0"><div class="MuiBox-root css-0"><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh">Looking for the best place to buy affordable coding devices at cheaper rate?</p><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh">Try amazon devices today!</p></div></a></div> !!! **Key Highlights** This comprehensive guide will equip you with the knowledge and skills to master NextAuth and MongoDB for secure authentication and role-based authorization in NextJS 14: - **Effortless NextAuth Integration:** Seamlessly integrate NextAuth into your NextJS 14 application for a streamlined authentication experience. - **MongoDB Authentication Backend:** Harness the power of MongoDB as your authentication backend, leveraging its robust data storage and management capabilities. - **Role-Based Authorization Implementation:** Implement role-based authorization to control user access and permissions, ensuring secure access to application features. - **NextJS Development Enhancement:** Elevate your NextJS development skills to the next level by mastering advanced authentication and authorization techniques. - **Nextjs App and Node Server Connection:** Connect your Nextjs App with a Node server to establish a secure communication channel. - **Access and Refresh Token Functionality:** Implement access and refresh token functionality to maintain user sessions and manage authentication refresh cycles. - **NextAuth JWT and Database Strategy with Database Adapter:** Utilize NextAuth JWT and database strategy with a database adapter to enhance security and streamline authentication processes. - **Server & client side data fetching:** Easily fetch data on both server & client side using SWR in the nextjs app. - **Data & form validation:** Learn how to validate form data client and server side using zod library. - **Data & form validation:** Learn how to validate form data client and server side using zod library. - **Protect API routes:** Learn how to protect server api routes using nextjs 14 middleware to implement both protected and public routes. - **Protect pages with auth session :** Learn how to use next auth session to protect private pages and require authentication. !!! warning Sponsored <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 css-x82yov" style="--Paper-shadow:0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)"><a title="Try Amazon today!" target="_blank" href="https://amzn.to/3C7FDwt"><div class="MuiBox-root css-0"><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh">Shop on Amazon today for unbeatable convenience, top deals, and an endless selection of products. Discover everything you need, from the latest tech to everyday essentials, all delivered quickly and securely. Don't miss out—experience hassle-free shopping at its best!</p><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh">Try Amazon today!</p></div></a></div> !!! **Target Audience** This guide is designed for a wide range of individuals interested in enhancing their NextJS authentication skills: - **NextJS Developers:** Developers seeking to elevate their NextJS development skills by mastering advanced authentication and authorization techniques. - **Web Security Specialists:** Aspiring web security specialists seeking to expand their knowledge of secure user authentication and authorization in NextJS applications. - **MongoDB Enthusiasts:** Enthusiasts eager to explore MongoDB's authentication capabilities and its integration with NextJS 14. **Embrace the Future of Secure NextJS Development** By embarking on this comprehensive journey, you will gain the necessary skills and knowledge to seamlessly implement authentication and role-based authorization within your NextJS 14 applications. This guide will empower you to: - **Effortlessly Set Up User Authentication:** Discover how to set up secure user authentication, ensuring a secure and personalized user experience. - **Implement Flawless Role-Based Access Control:** Implement role-based access control to manage user permissions, ensuring that users only access authorized application features. - **Harness NextJS 14, NextAuth, and MongoDB Adapter:** Leverage the power of NextJS 14, NextAuth, and MongoDB Adapter to create a smooth, secure, and scalable user authentication experience. **Enhance Your NextJS Skills** Whether you're a beginner or an experienced developer, this guide equips you with the tools and knowledge to effortlessly implement advanced authentication and authorization features in your NextJS projects. Level up your NextJS game and don't miss this opportunity to enhance your skills! > [Link to the repo can be found here](https://github.com/torver213/nextjs14-nextauth-nodeapi-yt) **Watch Now and Unlock Seamless Authentication** Embark on this journey to master NextAuth and MongoDB for secure authentication and role-based authorization in NextJS 14. Watch now and unlock the world of seamless authentication and role-based authorization in NextJS 14! Don't forget to like, subscribe, and share this knowledge with fellow developers! <iframe width="560" height="315" src="https://www.youtube.com/embed/JBo2DMegIxM?si=ojWz5x-1Iwy8FOF3" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> > Don't miss out—watch, subscribe, and share with your developer community!
implement dark mode & light mode in next.js 14 app router with material-ui without ui flickering
In this in-depth guide, learn how to seamlessly set up dark mode and light mode in your Next.js 14 app router application using Material-UI and css v...
### Introduction Dark mode has become a popular feature in modern web applications, enhancing user experience and adding a sleek, visually appealing touch. With Next.js 14 and Material-UI (MUI), you can seamlessly toggle between dark and light modes, giving users the flexibility to choose based on their preferences. One of the challenges, however, is ensuring that the UI doesn’t flicker during theme transitions due to Nextjs server side rendering. In this article, we’ll implement a flicker-free dark mode and light mode in Next.js 14 using the new App Router, Material-UI, and MUI CSS variables to manage theme states smoothly. !!! abstract Sponsored <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 css-x82yov" style="--Paper-shadow:0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)"><a title="Try amazon shopping today!" target="_blank" href="https://amzn.to/3NXWjct"><div class="MuiBox-root css-0"><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh">Looking for the best platform to upgrade your wardrobe?</p><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh" style="font-weight:400">Try amazon shopping today!</p></div></a></div> !!! ### Prerequisites Before we start, ensure you have: - **Node.js** and **npm** installed. - **Next.js 14** project setup. - **Material-UI (MUI)** for theme management. ### Follow the steps below to install the necessary packages Open your terminal and bootstrap a new nextjs project. 1. First, create a nextjs app ```bash npx create-next-app@14.2.16 nextjs-mui-theme ``` Open the project in your coding environment 2. Install the MUI dependencies: ```bash npm install @mui/material @emotion/react @emotion/styled next-themes ``` 3. Install MUI library for nextjs ```bash npm install @mui/material-nextjs/v15-appRouter ``` 4. Install Roboto fonts ```bash npm install @fontsource/roboto ``` 5. Copy & paste the code below in `src/app/layout.tsx` and ```ts react import '@fontsource/roboto/300.css'; import '@fontsource/roboto/400.css'; import '@fontsource/roboto/500.css'; import '@fontsource/roboto/700.css'; ``` 6. Install MUI icons library ```bash npm install @mui/icons-material ``` 7. Copy the code below and replace the code in the file `src/app/globals.css` ```css @import url(https://fonts.googleapis.com/icon?family=Material+Icons); html, body { max-width: 100vw; overflow-x: hidden; } * { box-sizing: border-box; padding: 0; margin: 0; } ``` !!! info Sponsored <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 css-x82yov" style="--Paper-shadow:0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)"><a title="Shop Smarter on Amazon: Unbeatable Deals & Top Picks!" target="_blank" href="https://amzn.to/3UIrYT7"><div class="MuiBox-root css-0"><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh">Looking for the best deals and top-rated products? Discover incredible savings on Amazon! From tech gadgets to home essentials, we’ve got everything you need—delivered straight to your door.</p><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh" style="font-weight:400">Shop Smarter on Amazon: Unbeatable Deals & Top Picks!</p></div></a></div> !!! 8. Install the package for generating dummy data ```bash npm i @faker-js/faker ``` If you did the above, your `package.json` should look like this ```json { "name": "nextjs-mui-theme", "version": "0.1.0", "private": true, "scripts": { "dev": "next dev", "build": "next build", "start": "next start", "lint": "next lint" }, "dependencies": { "@emotion/cache": "^11.13.1", "@emotion/react": "^11.13.3", "@emotion/styled": "^11.13.0", "@faker-js/faker": "^9.2.0", "@fontsource/roboto": "^5.1.0", "@mui/icons-material": "^6.1.6", "@mui/material": "^6.1.6", "@mui/material-nextjs": "^6.1.6", "next": "14.2.16", "react": "^18", "react-dom": "^18" }, "devDependencies": { "@types/node": "^20", "@types/react": "^18", "@types/react-dom": "^18", "eslint": "^8", "eslint-config-next": "14.2.16", "typescript": "^5" } } ``` 9. Create two directories in *src* directory - context - components 10. Open **context** driectory and create a file `AppThemeContext.tsx` and paste the following code. To handle theme switching, we’ll create a custom `ThemeProvider` component. This component will wrap our application, detect the theme preference (dark or light), and apply it without causing UI flickering. ```typescript react 'use client' import { createTheme, CssBaseline, responsiveFontSizes, ThemeProvider } from "@mui/material"; import { createContext, useContext, useMemo } from "react"; import type {} from '@mui/material/themeCssVarsAugmentation'; const AppThemeContext = createContext(null) const AppThemeProvider = (props: any) => { const theme = useMemo(() => { return responsiveFontSizes(createTheme({ cssVariables: { colorSchemeSelector: "class", disableCssColorScheme: true }, palette: { primary: { main: `rgb(10, 18, 42)`, contrastText: 'rgb(255, 255, 255)', }, secondary: { main: `rgb(27, 59, 111)`, contrastText: 'rgb(255, 255, 255)', } }, colorSchemes: { light: { palette: { primary: { main: `rgb(10, 18, 42)`, }, secondary: { main: `rgb(27, 59, 111)`, } } }, dark: { palette: { primary: { main: `rgb(10, 18, 42)`, }, secondary: { main: `rgb(27, 59, 111)`, } } } } })) }, []) return <AppThemeContext.Provider value={null}> <ThemeProvider theme={theme} disableTransitionOnChange> <CssBaseline enableColorScheme /> {props.children} </ThemeProvider> </AppThemeContext.Provider> } export const useAppThemeContext = () => useContext(AppThemeContext) export default AppThemeProvider ``` **Explanation** - We created a `theme` object to be used throughout our application - Code line 14 - 17, specifies the *cssVariables* config which enables css variables in MUI - We defined the *palette* for our app - We defined the *colorSchemes* which specifies our light and dark mode themes. This can be modified based on your needs. - **ThemeProvider:** This provider applies the selected MUI theme (either dark or light) to the entire app. You > Notice that we passed **theme** object to the ThemeProvider component - We called **CssBaseline** from *mui* with the prop *enableColorScheme* which will enable color schemes based on user selection or system default and reset the proper styles for our app to display well on different devices. - We exported our custom **AppThemeProvider** which will wrap the whole of our application. !!! success Sponsored <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 css-x82yov" style="--Paper-shadow:0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)"><a title="Checkout this amazing amazon offers!" target="_blank" href="https://amzn.to/4hvBpiJ"><div class="MuiBox-root css-0"><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh">Don’t miss out on exclusive offers, lightning-fast shipping, and the convenience of shopping from anywhere</p><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh" style="font-weight:400">Checkout this amazing amazon offers!</p></div></a></div> !!! 11. Open `src/app/layout.tsx` file and replace the following code ```typescript react import type { Metadata } from "next"; import '@fontsource/roboto/300.css'; import '@fontsource/roboto/400.css'; import '@fontsource/roboto/500.css'; import '@fontsource/roboto/700.css'; import { AppRouterCacheProvider } from '@mui/material-nextjs/v15-appRouter'; import "./globals.css"; import InitColorSchemeScript from "@mui/material/InitColorSchemeScript" import AppThemeProvider from "@/context/AppThemeContext"; import {MainNavbar} from "@/components" export const metadata: Metadata = { title: "Create Next App", description: "Generated by create next app", }; export default function RootLayout({ children, }: Readonly<{ children: React.ReactNode; }>) { return ( <html lang="en" suppressHydrationWarning> <body> <AppRouterCacheProvider options={{enableCssLayer: false}}> <AppThemeProvider> <InitColorSchemeScript attribute="class" /> <MainNavbar /> {children} </AppThemeProvider> </AppRouterCacheProvider> </body> </html> ); } ``` **Explanation** - We called **AppRouterCacheProvider** from mui nextjs library and wrap our children inside the *body* element. The component also accept an option of *enableCssLayer: false* - We imported our custom `AppThemeProvider` to wrap our whole app to apply our MUI styles. - We called `<InitiColorSchemeScript attribute="class" />` to initialize our default mode on the server without a flicker. Since *cssVariables* is enabled and initialized, this can be applied on the on server without a flicker. > Remember the `attribute="class"` must be the same value with the custom theme *cssVariables* config in `AppThemeContext.tsx` file `cssVariables: { colorSchemeSelector: "class" }` - Since we want our navbar to persist across pages, we called `<MainNavbar />` and then `{children}` which will be any component passed to the layout in this case the `page.tsx` component. 12. Open `src/components` directory and create 4 files namely; - `index.tsx` - `MainNavbar.tsx` - `Homepage.tsx` - `MediaCard.tsx` > Open `src/components/index.tsx` and paste the code below; ```typescript react export { default as MainNavbar } from "./MainNavbar" export { default as Homepage } from "./Homepage" ``` > Open `src/components/MainNavbar.tsx` and paste the code below; ```typescript react 'use client' import * as React from 'react'; import AppBar from '@mui/material/AppBar'; import Box from '@mui/material/Box'; import Toolbar from '@mui/material/Toolbar'; import IconButton from '@mui/material/IconButton'; import Typography from '@mui/material/Typography'; import Menu from '@mui/material/Menu'; import MenuIcon from '@mui/icons-material/Menu'; import Container from '@mui/material/Container'; import Avatar from '@mui/material/Avatar'; import Button from '@mui/material/Button'; import Tooltip from '@mui/material/Tooltip'; import MenuItem from '@mui/material/MenuItem'; import AdbIcon from '@mui/icons-material/Adb'; import DarkModeOutlinedIcon from '@mui/icons-material/DarkModeOutlined'; import LightModeOutlinedIcon from '@mui/icons-material/LightModeOutlined'; import { useColorScheme } from '@mui/material/styles'; const pages = ['Products', 'Pricing', 'Blog']; const settings = ['Profile', 'Account', 'Dashboard', 'Logout']; function MainNavbar() { const { mode, systemMode, setMode } = useColorScheme(); const [anchorElNav, setAnchorElNav] = React.useState<null | HTMLElement>(null); const [anchorElUser, setAnchorElUser] = React.useState<null | HTMLElement>(null); const handleOpenNavMenu = (event: React.MouseEvent<HTMLElement>) => { setAnchorElNav(event.currentTarget); }; const handleOpenUserMenu = (event: React.MouseEvent<HTMLElement>) => { setAnchorElUser(event.currentTarget); }; const handleCloseNavMenu = () => { setAnchorElNav(null); }; const handleCloseUserMenu = () => { setAnchorElUser(null); }; const toggleDarkTheme = React.useCallback(() => { if(mode){ const currMode = mode === 'dark' ? 'light' : 'dark'; setMode(currMode); } },[mode, systemMode]) return ( <AppBar position="fixed"> <Container maxWidth="xl"> <Toolbar disableGutters> <AdbIcon sx={{ display: { xs: 'none', md: 'flex' }, mr: 1 }} /> <Typography variant="h6" noWrap component="a" href="#app-bar-with-responsive-menu" sx={{ mr: 2, display: { xs: 'none', md: 'flex' }, fontFamily: 'monospace', fontWeight: 700, letterSpacing: '.3rem', color: 'inherit', textDecoration: 'none', }} > LOGO </Typography> <Box sx={{ flexGrow: 1, display: { xs: 'flex', md: 'none' } }}> <IconButton size="large" aria-label="account of current user" aria-controls="menu-appbar" aria-haspopup="true" onClick={handleOpenNavMenu} color="inherit" > <MenuIcon /> </IconButton> <Menu id="menu-appbar" anchorEl={anchorElNav} anchorOrigin={{ vertical: 'bottom', horizontal: 'left', }} keepMounted transformOrigin={{ vertical: 'top', horizontal: 'left', }} open={Boolean(anchorElNav)} onClose={handleCloseNavMenu} sx={{ display: { xs: 'block', md: 'none' } }} > {pages.map((page) => ( <MenuItem key={page} onClick={handleCloseNavMenu}> <Typography sx={{ textAlign: 'center' }}>{page}</Typography> </MenuItem> ))} </Menu> </Box> <AdbIcon sx={{ display: { xs: 'flex', md: 'none' }, mr: 1 }} /> <Typography variant="h5" noWrap component="a" href="#app-bar-with-responsive-menu" sx={{ mr: 2, display: { xs: 'flex', md: 'none' }, flexGrow: 1, fontFamily: 'monospace', fontWeight: 700, letterSpacing: '.3rem', color: 'inherit', textDecoration: 'none', }} > LOGO </Typography> <Box sx={{ flexGrow: 1, display: { xs: 'none', md: 'flex' } }}> {pages.map((page) => ( <Button key={page} onClick={handleCloseNavMenu} sx={{ my: 2, color: 'white', display: 'block' }} > {page} </Button> ))} </Box> <Box sx={{ flexGrow: 0, pr: 2 }}> <Tooltip title="Toggle Theme"> <IconButton size='large' color='inherit' onClick={() => toggleDarkTheme()} sx={{ p: 0 }}> { mode === "dark" ? <DarkModeOutlinedIcon /> : <LightModeOutlinedIcon /> } </IconButton> </Tooltip> </Box> <Box sx={{ flexGrow: 0 }}> <Tooltip title="Open settings"> <IconButton onClick={handleOpenUserMenu} sx={{ p: 0 }}> <Avatar alt="Remy Sharp" src="/static/images/avatar/2.jpg" /> </IconButton> </Tooltip> <Menu sx={{ mt: '45px' }} id="menu-appbar" anchorEl={anchorElUser} anchorOrigin={{ vertical: 'top', horizontal: 'right', }} keepMounted transformOrigin={{ vertical: 'top', horizontal: 'right', }} open={Boolean(anchorElUser)} onClose={handleCloseUserMenu} > {settings.map((setting) => ( <MenuItem key={setting} onClick={handleCloseUserMenu}> <Typography sx={{ textAlign: 'center' }}>{setting}</Typography> </MenuItem> ))} </Menu> </Box> </Toolbar> </Container> </AppBar> ); } export default MainNavbar; ``` **Explanation** - To implement theme toggle, we import `useColorScheme` on line 18 from *@mui/material/styles* - We called it on line 25 to get the `mode` and `systemMode` - We created a function **toggleDarkTheme** on line 44 to 49 to check if mode is set theme toggle the opposite then we called it on line 142 > Open `src/components/Homepage.tsx` and paste the code below; ```typescript react 'use client' import React from 'react' import { faker } from '@faker-js/faker'; import { Box, Container, Grid2 } from '@mui/material'; import MediaCard from './MediaCard'; const Homepage = () => { const data = Array.from({ length: 24 }).map(() => ({ id: faker.string.uuid(), title: faker.lorem.lines(1), content: faker.lorem.sentences(4), src: faker.image.urlPicsumPhotos() })) return ( <Box sx={[(theme) => ({ backgroundColor: theme.vars.palette.grey[300], ...theme.applyStyles("dark", { backgroundColor: theme.vars.palette.grey[900] }) })]} > <Container maxWidth="xl" sx={{mt: 9, pt: 2}}> <Grid2 container spacing={2}> {data.map(item => ( <Grid2 key={item.id} size={{lg: 3, md: 4, sm: 12, xs: 12}}> <MediaCard item={item} /> </Grid2> ))} </Grid2> </Container> </Box> ) } export default Homepage ``` !!! abstract Sponsored <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 css-x82yov" style="--Paper-shadow:0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)"><a title="Try this recommended laptops for coding on amazon" target="_blank" href="https://amzn.to/3UEiHLT"><div class="MuiBox-root css-0"><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh">Looking for the best laptops for coding?</p><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh" style="font-weight:400">Try this recommended laptops for coding on amazon!</p></div></a></div> !!! > Open `src/components/MediaCard.tsx` and paste the code below; ```typescript react import * as React from 'react'; import Card from '@mui/material/Card'; import CardActions from '@mui/material/CardActions'; import CardContent from '@mui/material/CardContent'; import CardMedia from '@mui/material/CardMedia'; import Button from '@mui/material/Button'; import Typography from '@mui/material/Typography'; type Item = { id: string, title: string, src: string, content: string} export default function MediaCard({item}: { item: Item}) { return ( <Card sx={{ height: "100%"}}> <CardMedia sx={{ height: 140 }} image={item.src} title={item.title} /> <CardContent> <Typography gutterBottom variant="h5" component="div"> {item.title} </Typography> <Typography variant="body2" sx={{ color: 'text.secondary' }}> {item.content} </Typography> </CardContent> <CardActions sx={{justifyContent: "space-between"}}> <Button color='inherit' variant='outlined' size="small">Share</Button> <Button color='inherit' variant='outlined' size="small">Learn More</Button> </CardActions> </Card> ); } ``` 13. Open `src/app/page.tsx` file and paste the following code ```typescript react import { Homepage } from "@/components"; export default function Home() { return ( <Homepage />); } ``` 14. Open your terminal within vs code or your chosen environment and run the command the blow to start the nextjs project. ```bash npm run dev ``` The above command should start a nextjs server listening on port 3000 like; `http://localhost:3000` Go ahead and open it in the browser and navigate to the above url and you should see your project running! With the above implementation you should be able to toggle between light and dark mode without UI flickering. !!! tip Sponsored <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 css-x82yov" style="--Paper-shadow:0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)"><a title="Unlock Huge Savings with Amazon’s Best Coupons! Shop & Save Big!" target="_blank" href="https://amzn.to/4fcO3Sb"><div class="MuiBox-root css-0"><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh">Why pay full price when you can save more? Find the latest high-value Amazon coupons and discounts on your favorite products! From electronics to fashion, enjoy exclusive savings and special offers that help you get more for less. Don’t miss out—shop today and take advantage of Amazon’s unbeatable deals! 💸🎉</p><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh" style="font-weight:400">Unlock Huge Savings with Amazon’s Best Coupons! Shop & Save Big!</p></div></a></div> !!! ### Minimize Flickering Using `ThemeProvider`’s `defaultMode="system"` and `InitColorSchemeScript`'s `defaultMode="system"` ensures that the app initially matches the user’s system theme on load. This approach minimizes the risk of a flicker effect and provides a smoother experience. If the above are not provided, the system's default mode will picked by default. ### Conclusion You’ve successfully implemented dark mode and light mode in your Next.js 14 app using MUI without flickering. Here are some additional tips for enhancing your implementation: - **System Theme Detection:** Mui ThemeProvider’ `defaultTheme="system"` applies the system’s theme by default, ensuring that users start with their preferred theme. - **Server-Side Rendering:** If using SSR, this implementation handles theme detection automatically to avoid flickering. - **Customization:** You can further customize `light` and `dark` in `AppThemeContext.tsx` for brand-specific colors, fonts, and more! By following these steps, you can provide a smooth, flicker-free dark mode experience in your Next.js app, enhancing both usability and visual appeal. !!! danger Sponsored <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 css-x82yov" style="--Paper-shadow:0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)"><a title="Try Monetag today and start monetizing your content instantly!" target="_blank" href="https://monetag.com/?ref_id=uawc"><div class="MuiBox-root css-0"><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh">Looking for the best platform to monetize your content?</p><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh" style="font-weight:400">Try Monetag today and start monetizing your content instantly!</p></div></a></div> !!! ### Source code For the full implementation, you can find the source code here [Nextjs Mui Theme Code](https://github.com/codesermon/nextjs-mui-theme) ### Youtube Video _Please like, comment, subscribe and turn notifications for more awesome videos like this_ <iframe width="560" height="315" src="https://www.youtube.com/embed/5ENPhdEMewg?si=YBFgzyxXO2vvWl5N" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> ### References [Read more on CSS theme variables](https://mui.com/material-ui/customization/css-theme-variables/overview/)
understanding cross origin resource sharing (cors) in reactjs & nodejs
CORS (Cross-Origin Resource Sharing) is a security mechanism that allows client applications to requ...
## What is CORS? **Cross-origin resource sharing (CORS)** is a mechanism that allows a client application to request restricted resources hosted on server from a different origin. These resources may include; web fonts, videos, scripts, iframes, images and stylesheets. By default, client applications making AJAX requests are only allowed to request resources that live on the same origin as the location where the client application is running. CORS defines a way in which a browser and server can interact to determine whether it is safe to allow the cross-origin request. If an application running on different domain tries to make a XMLHttpRequest to a different domain, it will be blocked by same-origin policy. It extends the same-origin policy and offers freedom and functionality than simply same-origin requests and it is more secured. Poor configuration & implementation of CORS policy could lead to data access denial, data theft and potential cross-domain attacks. !!! abstract Sponsored <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 css-x82yov" style="--Paper-shadow:0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)"><p class="MuiTypography-root MuiTypography-body1 css-fyswvn">Upgrade your tech game on Amazon! Find the latest computers, tablets, and accessories at unbeatable prices, with fast shipping and top-rated brands. Get your perfect device today!</p><a title="Amazon Movers & Shakers in Computers & Accessories" target="_blank" href="https://amzn.to/4f3U6Im">Amazon Movers & Shakers in Computers & Accessories</a></div> !!! ## Why is CORS important? Most of the time, you client application only needs to access resources within the same origin but there are scenarios where your application needs to request resources residing on another domain and that’s where CORS comes in. This could include your client application (React js website) makes calls to different API backend running on different domains to access resources such as images, web fonts, videos, files e.t.c Any origin that differs from the location your client app is running on such as different scheme, domain or port needs CORS configuration in order to properly interact. This could also serve as a big security measure if your CORS is properly configured. Different CORS request types There are two types CORS requests which include; 1. Simple requests with HTTP methods as GET, POST or HEAD 2. Preflight requests with HTTP methods DELETE, PATCH, PUT e.t.c If any of the preflight HTTP methods is used to make an **XMLHttpRequest**, the browser makes an automatic preflight request using the OPTIONS method. This call is used to determine if the CORS policy on the server supports the preflight request and whether or not the server can handle such request. In this article, we are going to focus majorly on how to add CORS to a react js application and Node.js Express RESTful API. !!! caution Sponsored <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 css-x82yov" style="--Paper-shadow:0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)"><p class="MuiTypography-root MuiTypography-body1 css-fyswvn">Monetag is your number platform to monetize your content hassle free. You don't need to be tech expert to do it.</p><a title="Looking for the best platform to monetize your content?" target="_blank" href="https://monetag.com/?ref_id=uawc">Try Monetag Today!</a></div> !!! ## Using CORS in react.js app and Node.js express REST API In this article we are going to discuss the following; 1. How to configure CORS to allow all domains to send requests to your node js server api 2. How to configure CORS to allow a single domain to communicate with your node js server. 3. How to configure CORS to allow multiple domains whitelisted by you to connect to your node js server. 4. How to configure CORS with express js to allow client server communication 5. How to proxy request in react js application to a node js server. 6. How to fix CORS error Blocked by CORS policy ## How to fix CORS error Blocked by CORS policy If you are react js developer, you may have come across CORS error, request to a particular URI is blocked by CORS policy. This is sometimes weird at first and if you aren’t familiar with CORS, you start second guessing if your code is buggy. No, your code isn’t buggy but it is the way browsers behave by default when you’re trying to request resources to another domain. In this article, we’re going to assume your client app is hosted on http://localhost:3000 and your server (REST API) is hosted on http://localhost:5000 Anyways, there are two ways to fix this in a react.js application which include; ## 1. Proxy configuration in package.json Using proxy configuration within your react.js app **package.json** file. One thing with this solution is that it only works in development environment unless you have a way of making it to work in production. In order to temporary fix the error, open your react js app **package.json** file and add the following configuration. ```javascript //other config keys { "proxy": "http://localhost:5000" } ``` If you noticed, the above configuration points to our server URL and this will allow you to make XMLHttpRequest in your client app running on the above URL. ## 2. Using CORS configuration In order to make use of CORS, I will assume you’re making use axios library in your client-side application. Remember this is not library specific, so you can make use of native browser FETCH API. Supposing you create an instance of axios using the code below ```javascript import axios from “axios” export const Axios = axios.create({ baseURL: "http://localhost:5000" withCredentials: true }) ``` The **baseURL** in the configuration above points to the URL of your node.js express API and the **withCredentials** property specifies if we want to share cookies or authentication headers with our server. The **withCredentials** property is totally optional and you don’t necessarily need to specify it unless you want to share cookies and auth headers. !!! abstract Sponsored <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 css-x82yov" style="--Paper-shadow:0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)"><p class="MuiTypography-root MuiTypography-body1 css-fyswvn">Discover endless deals on Amazon! From fashion and tech to home essentials and more, find everything you need in one place, with fast delivery and top-notch service. Start shopping today!</p><a title="Shop Amazon Today!" target="_blank" href="https://amzn.to/40tbSjV">Shop Amazon Today!</a></div> !!! **How to add CORS in node.js express API** In order to add CORS to our API, there are different ways by which you can accomplish this. It could be by manually writing an express middleware and telling your server which requests to allow and from which origin or by using CORS npm library which has done much of the heavy lifting for us. In this article, we will be using cors npm library which can be easily passed as an express middleware. First of all, install calls on your server-side app by running the command ```bash npm install cors ``` Then you can add it as a middleware like this ```javascript const express = require("express"); const cors = require("cors"); const app = express(); //use cors as middleware app.use(cors()) ``` The above code is the default way of adding CORS as an express middleware but what if you want to specify the origin of your client app? Well let’s learn different ways to configure CORS in node js app. #### Allow requests from all domains. To allow our node.js server to handle all requests from all domains in our application, we will have to configure cors and pass it an origin key with a wildcard value shown below. ```javascript //other imports app.use( cors({ origin: "*", }) ); ``` The issue with the above configuration is that, you client-side application **CANNOT** share cookies nor authentication headers even if the credentials key is passed with a value of true as shown below. **Note:** The origin key in cors option CORS take different option types such string, boolean, function or an array. ```javascript //other imports app.use( cors({ origin: "*", credentials: true }) ) ``` Another key important thing to note is that, whenever you are not passing **`withCredentials: true`** in your client request API, DO NOT pass **`credentials: true`** in your cors config server-side most especially if you are using wildcard (*) as the origin of your request header. #### Tell CORS to set the origin to the request origin In order to configure CORS to set the origin to the request origin, simply pass a boolean true value to origin key as shown below; ```javascript //other imports app.use( cors({ origin: true, credentials: true }) ) ``` Although this will allow your client app to share cookies and auth headers with your server unlike using wildcard but this also is not well secure enough unless it’s an open API. #### Configure CORS to set the origin to a single domain In order to configure cors to set the origin to a single domain, simply pass a string true value to origin key as shown below; ```javascript //other imports app.use( cors({ origin: "http://localhost:3000", credentials: true }) ) ``` The above configuration will allow your client app to accept requests only from http://localhost:3000 and share cookies and auth headers with your server. This configuration is tightly secure but not robust enough. #### Configure CORS to set the origin to multiple whitelisted domains What if you have microservice applications hosted on different domains or you want different domains to make requests to your API? Well, you can simply configure cors passing by an array of allowed domains to the origin key as shown below; ```javascript //other imports const allowedDomains = ["http://localhost:3000", "http://localhost:4000", "http://localhost:6000"] app.use( cors({ origin: allowedDomains, credentials: true }) ) ``` The above configuration will allow your client app to accept requests from any of the above domains listed in the array and share cookies and auth headers with your server. CORS middleware can be passed as a global middleware and on a single route but all the methods shown above are ways to globally configure your CORS within your app. Lets briefly see how we can pass CORS middleware on a single route. Note that, all the ways described above can be use on your routes as well. ```javascript const allowedDomains = ["http://localhost:3000", "http://localhost:4000", "http://localhost:6000"] app.get("/api/posts", cors({ origin: allowedDomains, credentials: true }), (req, res) =>{ res.send("everything still works") }) ``` !!! attention Note Whenever you’re a making a client-side request with the option of **`withCredentials: true,`** ensure your CORS configuration is passed **`credentials: true`** as an option as well else cookies won’t be shared. Another key important; thing to note is that, whenever you’re using wildcard (*) as the origin, DO NOT use **`withCredentials: true`** on the client and **`credentials: true`** on server !!! ## Summary: In this article, you have learnt that CORS is a mechanism that allows requests from a particular domain to be accepted by another domain and possibly share resources with each other. You got to understand that different ways by which you can configure your CORS to allow effective communication between client apps and servers. CORS, if done properly can serve as one of the security measures ensuring that your server only accepts requests from known domains. !!! success Sponsored <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 css-x82yov" style="--Paper-shadow:0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)"><p class="MuiTypography-root MuiTypography-body1 css-fyswvn">Monetag brings you exclusive product offers you don’t want to miss!</p><a title="Check out these amazing deals!" target="_blank" href="https://chikraighotoops.com/4/8313667">Check out these amazing deals!</a></div> !!! ## Video Tutorial If you are the visual type like me, go ahead and watch the video below. Please don't forget to like, share, comment, subscribe and turn on notification as that will give me the motivation to do more awesome videos and tutorials like this. <iframe width="560" height="315" src="https://www.youtube.com/embed/QZTOhHZY_LM?si=Q2K12x6j76ryFcZL" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> **REFERENCES** If you want to read more about CORS, visit the following links [What is cors? ](https://en.wikipedia.org/wiki/Cross-origin_resource_sharing ) [A guide to Cors](https://auth0.com/blog/cors-tutorial-a-guide-to-cross-origin-resource-sharing/) [CORS](https://portswigger.net/web-security/cors) [What is CORS?](https://www.stackhawk.com/blog/what-is-cors/ )
implement dark mode & light mode in next.js 14 app router with material-ui without ui flickering
In this in-depth guide, learn how to seamlessly set up dark mode and light mode in your Next.js 14 ...
### Introduction Dark mode has become a popular feature in modern web applications, enhancing user experience and adding a sleek, visually appealing touch. With Next.js 14 and Material-UI (MUI), you can seamlessly toggle between dark and light modes, giving users the flexibility to choose based on their preferences. One of the challenges, however, is ensuring that the UI doesn’t flicker during theme transitions due to Nextjs server side rendering. In this article, we’ll implement a flicker-free dark mode and light mode in Next.js 14 using the new App Router, Material-UI, and MUI CSS variables to manage theme states smoothly. !!! abstract Sponsored <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 css-x82yov" style="--Paper-shadow:0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)"><a title="Try amazon shopping today!" target="_blank" href="https://amzn.to/3NXWjct"><div class="MuiBox-root css-0"><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh">Looking for the best platform to upgrade your wardrobe?</p><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh" style="font-weight:400">Try amazon shopping today!</p></div></a></div> !!! ### Prerequisites Before we start, ensure you have: - **Node.js** and **npm** installed. - **Next.js 14** project setup. - **Material-UI (MUI)** for theme management. ### Follow the steps below to install the necessary packages Open your terminal and bootstrap a new nextjs project. 1. First, create a nextjs app ```bash npx create-next-app@14.2.16 nextjs-mui-theme ``` Open the project in your coding environment 2. Install the MUI dependencies: ```bash npm install @mui/material @emotion/react @emotion/styled next-themes ``` 3. Install MUI library for nextjs ```bash npm install @mui/material-nextjs/v15-appRouter ``` 4. Install Roboto fonts ```bash npm install @fontsource/roboto ``` 5. Copy & paste the code below in `src/app/layout.tsx` and ```ts react import '@fontsource/roboto/300.css'; import '@fontsource/roboto/400.css'; import '@fontsource/roboto/500.css'; import '@fontsource/roboto/700.css'; ``` 6. Install MUI icons library ```bash npm install @mui/icons-material ``` 7. Copy the code below and replace the code in the file `src/app/globals.css` ```css @import url(https://fonts.googleapis.com/icon?family=Material+Icons); html, body { max-width: 100vw; overflow-x: hidden; } * { box-sizing: border-box; padding: 0; margin: 0; } ``` !!! info Sponsored <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 css-x82yov" style="--Paper-shadow:0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)"><a title="Shop Smarter on Amazon: Unbeatable Deals & Top Picks!" target="_blank" href="https://amzn.to/3UIrYT7"><div class="MuiBox-root css-0"><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh">Looking for the best deals and top-rated products? Discover incredible savings on Amazon! From tech gadgets to home essentials, we’ve got everything you need—delivered straight to your door.</p><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh" style="font-weight:400">Shop Smarter on Amazon: Unbeatable Deals & Top Picks!</p></div></a></div> !!! 8. Install the package for generating dummy data ```bash npm i @faker-js/faker ``` If you did the above, your `package.json` should look like this ```json { "name": "nextjs-mui-theme", "version": "0.1.0", "private": true, "scripts": { "dev": "next dev", "build": "next build", "start": "next start", "lint": "next lint" }, "dependencies": { "@emotion/cache": "^11.13.1", "@emotion/react": "^11.13.3", "@emotion/styled": "^11.13.0", "@faker-js/faker": "^9.2.0", "@fontsource/roboto": "^5.1.0", "@mui/icons-material": "^6.1.6", "@mui/material": "^6.1.6", "@mui/material-nextjs": "^6.1.6", "next": "14.2.16", "react": "^18", "react-dom": "^18" }, "devDependencies": { "@types/node": "^20", "@types/react": "^18", "@types/react-dom": "^18", "eslint": "^8", "eslint-config-next": "14.2.16", "typescript": "^5" } } ``` 9. Create two directories in *src* directory - context - components 10. Open **context** driectory and create a file `AppThemeContext.tsx` and paste the following code. To handle theme switching, we’ll create a custom `ThemeProvider` component. This component will wrap our application, detect the theme preference (dark or light), and apply it without causing UI flickering. ```typescript react 'use client' import { createTheme, CssBaseline, responsiveFontSizes, ThemeProvider } from "@mui/material"; import { createContext, useContext, useMemo } from "react"; import type {} from '@mui/material/themeCssVarsAugmentation'; const AppThemeContext = createContext(null) const AppThemeProvider = (props: any) => { const theme = useMemo(() => { return responsiveFontSizes(createTheme({ cssVariables: { colorSchemeSelector: "class", disableCssColorScheme: true }, palette: { primary: { main: `rgb(10, 18, 42)`, contrastText: 'rgb(255, 255, 255)', }, secondary: { main: `rgb(27, 59, 111)`, contrastText: 'rgb(255, 255, 255)', } }, colorSchemes: { light: { palette: { primary: { main: `rgb(10, 18, 42)`, }, secondary: { main: `rgb(27, 59, 111)`, } } }, dark: { palette: { primary: { main: `rgb(10, 18, 42)`, }, secondary: { main: `rgb(27, 59, 111)`, } } } } })) }, []) return <AppThemeContext.Provider value={null}> <ThemeProvider theme={theme} disableTransitionOnChange> <CssBaseline enableColorScheme /> {props.children} </ThemeProvider> </AppThemeContext.Provider> } export const useAppThemeContext = () => useContext(AppThemeContext) export default AppThemeProvider ``` **Explanation** - We created a `theme` object to be used throughout our application - Code line 14 - 17, specifies the *cssVariables* config which enables css variables in MUI - We defined the *palette* for our app - We defined the *colorSchemes* which specifies our light and dark mode themes. This can be modified based on your needs. - **ThemeProvider:** This provider applies the selected MUI theme (either dark or light) to the entire app. You > Notice that we passed **theme** object to the ThemeProvider component - We called **CssBaseline** from *mui* with the prop *enableColorScheme* which will enable color schemes based on user selection or system default and reset the proper styles for our app to display well on different devices. - We exported our custom **AppThemeProvider** which will wrap the whole of our application. !!! success Sponsored <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 css-x82yov" style="--Paper-shadow:0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)"><a title="Checkout this amazing amazon offers!" target="_blank" href="https://amzn.to/4hvBpiJ"><div class="MuiBox-root css-0"><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh">Don’t miss out on exclusive offers, lightning-fast shipping, and the convenience of shopping from anywhere</p><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh" style="font-weight:400">Checkout this amazing amazon offers!</p></div></a></div> !!! 11. Open `src/app/layout.tsx` file and replace the following code ```typescript react import type { Metadata } from "next"; import '@fontsource/roboto/300.css'; import '@fontsource/roboto/400.css'; import '@fontsource/roboto/500.css'; import '@fontsource/roboto/700.css'; import { AppRouterCacheProvider } from '@mui/material-nextjs/v15-appRouter'; import "./globals.css"; import InitColorSchemeScript from "@mui/material/InitColorSchemeScript" import AppThemeProvider from "@/context/AppThemeContext"; import {MainNavbar} from "@/components" export const metadata: Metadata = { title: "Create Next App", description: "Generated by create next app", }; export default function RootLayout({ children, }: Readonly<{ children: React.ReactNode; }>) { return ( <html lang="en" suppressHydrationWarning> <body> <AppRouterCacheProvider options={{enableCssLayer: false}}> <AppThemeProvider> <InitColorSchemeScript attribute="class" /> <MainNavbar /> {children} </AppThemeProvider> </AppRouterCacheProvider> </body> </html> ); } ``` **Explanation** - We called **AppRouterCacheProvider** from mui nextjs library and wrap our children inside the *body* element. The component also accept an option of *enableCssLayer: false* - We imported our custom `AppThemeProvider` to wrap our whole app to apply our MUI styles. - We called `<InitiColorSchemeScript attribute="class" />` to initialize our default mode on the server without a flicker. Since *cssVariables* is enabled and initialized, this can be applied on the on server without a flicker. > Remember the `attribute="class"` must be the same value with the custom theme *cssVariables* config in `AppThemeContext.tsx` file `cssVariables: { colorSchemeSelector: "class" }` - Since we want our navbar to persist across pages, we called `<MainNavbar />` and then `{children}` which will be any component passed to the layout in this case the `page.tsx` component. 12. Open `src/components` directory and create 4 files namely; - `index.tsx` - `MainNavbar.tsx` - `Homepage.tsx` - `MediaCard.tsx` > Open `src/components/index.tsx` and paste the code below; ```typescript react export { default as MainNavbar } from "./MainNavbar" export { default as Homepage } from "./Homepage" ``` > Open `src/components/MainNavbar.tsx` and paste the code below; ```typescript react 'use client' import * as React from 'react'; import AppBar from '@mui/material/AppBar'; import Box from '@mui/material/Box'; import Toolbar from '@mui/material/Toolbar'; import IconButton from '@mui/material/IconButton'; import Typography from '@mui/material/Typography'; import Menu from '@mui/material/Menu'; import MenuIcon from '@mui/icons-material/Menu'; import Container from '@mui/material/Container'; import Avatar from '@mui/material/Avatar'; import Button from '@mui/material/Button'; import Tooltip from '@mui/material/Tooltip'; import MenuItem from '@mui/material/MenuItem'; import AdbIcon from '@mui/icons-material/Adb'; import DarkModeOutlinedIcon from '@mui/icons-material/DarkModeOutlined'; import LightModeOutlinedIcon from '@mui/icons-material/LightModeOutlined'; import { useColorScheme } from '@mui/material/styles'; const pages = ['Products', 'Pricing', 'Blog']; const settings = ['Profile', 'Account', 'Dashboard', 'Logout']; function MainNavbar() { const { mode, systemMode, setMode } = useColorScheme(); const [anchorElNav, setAnchorElNav] = React.useState<null | HTMLElement>(null); const [anchorElUser, setAnchorElUser] = React.useState<null | HTMLElement>(null); const handleOpenNavMenu = (event: React.MouseEvent<HTMLElement>) => { setAnchorElNav(event.currentTarget); }; const handleOpenUserMenu = (event: React.MouseEvent<HTMLElement>) => { setAnchorElUser(event.currentTarget); }; const handleCloseNavMenu = () => { setAnchorElNav(null); }; const handleCloseUserMenu = () => { setAnchorElUser(null); }; const toggleDarkTheme = React.useCallback(() => { if(mode){ const currMode = mode === 'dark' ? 'light' : 'dark'; setMode(currMode); } },[mode, systemMode]) return ( <AppBar position="fixed"> <Container maxWidth="xl"> <Toolbar disableGutters> <AdbIcon sx={{ display: { xs: 'none', md: 'flex' }, mr: 1 }} /> <Typography variant="h6" noWrap component="a" href="#app-bar-with-responsive-menu" sx={{ mr: 2, display: { xs: 'none', md: 'flex' }, fontFamily: 'monospace', fontWeight: 700, letterSpacing: '.3rem', color: 'inherit', textDecoration: 'none', }} > LOGO </Typography> <Box sx={{ flexGrow: 1, display: { xs: 'flex', md: 'none' } }}> <IconButton size="large" aria-label="account of current user" aria-controls="menu-appbar" aria-haspopup="true" onClick={handleOpenNavMenu} color="inherit" > <MenuIcon /> </IconButton> <Menu id="menu-appbar" anchorEl={anchorElNav} anchorOrigin={{ vertical: 'bottom', horizontal: 'left', }} keepMounted transformOrigin={{ vertical: 'top', horizontal: 'left', }} open={Boolean(anchorElNav)} onClose={handleCloseNavMenu} sx={{ display: { xs: 'block', md: 'none' } }} > {pages.map((page) => ( <MenuItem key={page} onClick={handleCloseNavMenu}> <Typography sx={{ textAlign: 'center' }}>{page}</Typography> </MenuItem> ))} </Menu> </Box> <AdbIcon sx={{ display: { xs: 'flex', md: 'none' }, mr: 1 }} /> <Typography variant="h5" noWrap component="a" href="#app-bar-with-responsive-menu" sx={{ mr: 2, display: { xs: 'flex', md: 'none' }, flexGrow: 1, fontFamily: 'monospace', fontWeight: 700, letterSpacing: '.3rem', color: 'inherit', textDecoration: 'none', }} > LOGO </Typography> <Box sx={{ flexGrow: 1, display: { xs: 'none', md: 'flex' } }}> {pages.map((page) => ( <Button key={page} onClick={handleCloseNavMenu} sx={{ my: 2, color: 'white', display: 'block' }} > {page} </Button> ))} </Box> <Box sx={{ flexGrow: 0, pr: 2 }}> <Tooltip title="Toggle Theme"> <IconButton size='large' color='inherit' onClick={() => toggleDarkTheme()} sx={{ p: 0 }}> { mode === "dark" ? <DarkModeOutlinedIcon /> : <LightModeOutlinedIcon /> } </IconButton> </Tooltip> </Box> <Box sx={{ flexGrow: 0 }}> <Tooltip title="Open settings"> <IconButton onClick={handleOpenUserMenu} sx={{ p: 0 }}> <Avatar alt="Remy Sharp" src="/static/images/avatar/2.jpg" /> </IconButton> </Tooltip> <Menu sx={{ mt: '45px' }} id="menu-appbar" anchorEl={anchorElUser} anchorOrigin={{ vertical: 'top', horizontal: 'right', }} keepMounted transformOrigin={{ vertical: 'top', horizontal: 'right', }} open={Boolean(anchorElUser)} onClose={handleCloseUserMenu} > {settings.map((setting) => ( <MenuItem key={setting} onClick={handleCloseUserMenu}> <Typography sx={{ textAlign: 'center' }}>{setting}</Typography> </MenuItem> ))} </Menu> </Box> </Toolbar> </Container> </AppBar> ); } export default MainNavbar; ``` **Explanation** - To implement theme toggle, we import `useColorScheme` on line 18 from *@mui/material/styles* - We called it on line 25 to get the `mode` and `systemMode` - We created a function **toggleDarkTheme** on line 44 to 49 to check if mode is set theme toggle the opposite then we called it on line 142 > Open `src/components/Homepage.tsx` and paste the code below; ```typescript react 'use client' import React from 'react' import { faker } from '@faker-js/faker'; import { Box, Container, Grid2 } from '@mui/material'; import MediaCard from './MediaCard'; const Homepage = () => { const data = Array.from({ length: 24 }).map(() => ({ id: faker.string.uuid(), title: faker.lorem.lines(1), content: faker.lorem.sentences(4), src: faker.image.urlPicsumPhotos() })) return ( <Box sx={[(theme) => ({ backgroundColor: theme.vars.palette.grey[300], ...theme.applyStyles("dark", { backgroundColor: theme.vars.palette.grey[900] }) })]} > <Container maxWidth="xl" sx={{mt: 9, pt: 2}}> <Grid2 container spacing={2}> {data.map(item => ( <Grid2 key={item.id} size={{lg: 3, md: 4, sm: 12, xs: 12}}> <MediaCard item={item} /> </Grid2> ))} </Grid2> </Container> </Box> ) } export default Homepage ``` !!! abstract Sponsored <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 css-x82yov" style="--Paper-shadow:0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)"><a title="Try this recommended laptops for coding on amazon" target="_blank" href="https://amzn.to/3UEiHLT"><div class="MuiBox-root css-0"><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh">Looking for the best laptops for coding?</p><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh" style="font-weight:400">Try this recommended laptops for coding on amazon!</p></div></a></div> !!! > Open `src/components/MediaCard.tsx` and paste the code below; ```typescript react import * as React from 'react'; import Card from '@mui/material/Card'; import CardActions from '@mui/material/CardActions'; import CardContent from '@mui/material/CardContent'; import CardMedia from '@mui/material/CardMedia'; import Button from '@mui/material/Button'; import Typography from '@mui/material/Typography'; type Item = { id: string, title: string, src: string, content: string} export default function MediaCard({item}: { item: Item}) { return ( <Card sx={{ height: "100%"}}> <CardMedia sx={{ height: 140 }} image={item.src} title={item.title} /> <CardContent> <Typography gutterBottom variant="h5" component="div"> {item.title} </Typography> <Typography variant="body2" sx={{ color: 'text.secondary' }}> {item.content} </Typography> </CardContent> <CardActions sx={{justifyContent: "space-between"}}> <Button color='inherit' variant='outlined' size="small">Share</Button> <Button color='inherit' variant='outlined' size="small">Learn More</Button> </CardActions> </Card> ); } ``` 13. Open `src/app/page.tsx` file and paste the following code ```typescript react import { Homepage } from "@/components"; export default function Home() { return ( <Homepage />); } ``` 14. Open your terminal within vs code or your chosen environment and run the command the blow to start the nextjs project. ```bash npm run dev ``` The above command should start a nextjs server listening on port 3000 like; `http://localhost:3000` Go ahead and open it in the browser and navigate to the above url and you should see your project running! With the above implementation you should be able to toggle between light and dark mode without UI flickering. !!! tip Sponsored <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 css-x82yov" style="--Paper-shadow:0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)"><a title="Unlock Huge Savings with Amazon’s Best Coupons! Shop & Save Big!" target="_blank" href="https://amzn.to/4fcO3Sb"><div class="MuiBox-root css-0"><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh">Why pay full price when you can save more? Find the latest high-value Amazon coupons and discounts on your favorite products! From electronics to fashion, enjoy exclusive savings and special offers that help you get more for less. Don’t miss out—shop today and take advantage of Amazon’s unbeatable deals! 💸🎉</p><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh" style="font-weight:400">Unlock Huge Savings with Amazon’s Best Coupons! Shop & Save Big!</p></div></a></div> !!! ### Minimize Flickering Using `ThemeProvider`’s `defaultMode="system"` and `InitColorSchemeScript`'s `defaultMode="system"` ensures that the app initially matches the user’s system theme on load. This approach minimizes the risk of a flicker effect and provides a smoother experience. If the above are not provided, the system's default mode will picked by default. ### Conclusion You’ve successfully implemented dark mode and light mode in your Next.js 14 app using MUI without flickering. Here are some additional tips for enhancing your implementation: - **System Theme Detection:** Mui ThemeProvider’ `defaultTheme="system"` applies the system’s theme by default, ensuring that users start with their preferred theme. - **Server-Side Rendering:** If using SSR, this implementation handles theme detection automatically to avoid flickering. - **Customization:** You can further customize `light` and `dark` in `AppThemeContext.tsx` for brand-specific colors, fonts, and more! By following these steps, you can provide a smooth, flicker-free dark mode experience in your Next.js app, enhancing both usability and visual appeal. !!! danger Sponsored <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 css-x82yov" style="--Paper-shadow:0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)"><a title="Try Monetag today and start monetizing your content instantly!" target="_blank" href="https://monetag.com/?ref_id=uawc"><div class="MuiBox-root css-0"><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh">Looking for the best platform to monetize your content?</p><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh" style="font-weight:400">Try Monetag today and start monetizing your content instantly!</p></div></a></div> !!! ### Source code For the full implementation, you can find the source code here [Nextjs Mui Theme Code](https://github.com/codesermon/nextjs-mui-theme) ### Youtube Video _Please like, comment, subscribe and turn notifications for more awesome videos like this_ <iframe width="560" height="315" src="https://www.youtube.com/embed/5ENPhdEMewg?si=YBFgzyxXO2vvWl5N" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> ### References [Read more on CSS theme variables](https://mui.com/material-ui/customization/css-theme-variables/overview/)
nextjs 14 app router authentication & role-based authorization using nextauth & mongodb adapter
This comprehensive guide provides developers with the knowledge and skills to implement secure user ...
**Unlock the Potential of NextJS 14: Mastering NextAuth & MongoDB for Secure Authentication and Role-Based Authorization** In the dynamic realm of web development, security and user authentication are paramount. NextJS 14, a popular React framework, has emerged as a powerful tool for building secure and scalable web applications. With NextAuth and MongoDB, developers can seamlessly integrate user authentication and role-based authorization into their NextJS applications, ensuring a secure and personalized user experience. !!! abstract Sponsored <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 css-x82yov" style="--Paper-shadow:0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)"><a title="Try amazon devices today!" target="_blank" href="https://amzn.to/4eiEQX0"><div class="MuiBox-root css-0"><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh">Looking for the best place to buy affordable coding devices at cheaper rate?</p><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh">Try amazon devices today!</p></div></a></div> !!! **Key Highlights** This comprehensive guide will equip you with the knowledge and skills to master NextAuth and MongoDB for secure authentication and role-based authorization in NextJS 14: - **Effortless NextAuth Integration:** Seamlessly integrate NextAuth into your NextJS 14 application for a streamlined authentication experience. - **MongoDB Authentication Backend:** Harness the power of MongoDB as your authentication backend, leveraging its robust data storage and management capabilities. - **Role-Based Authorization Implementation:** Implement role-based authorization to control user access and permissions, ensuring secure access to application features. - **NextJS Development Enhancement:** Elevate your NextJS development skills to the next level by mastering advanced authentication and authorization techniques. - **Nextjs App and Node Server Connection:** Connect your Nextjs App with a Node server to establish a secure communication channel. - **Access and Refresh Token Functionality:** Implement access and refresh token functionality to maintain user sessions and manage authentication refresh cycles. - **NextAuth JWT and Database Strategy with Database Adapter:** Utilize NextAuth JWT and database strategy with a database adapter to enhance security and streamline authentication processes. - **Server & client side data fetching:** Easily fetch data on both server & client side using SWR in the nextjs app. - **Data & form validation:** Learn how to validate form data client and server side using zod library. - **Data & form validation:** Learn how to validate form data client and server side using zod library. - **Protect API routes:** Learn how to protect server api routes using nextjs 14 middleware to implement both protected and public routes. - **Protect pages with auth session :** Learn how to use next auth session to protect private pages and require authentication. !!! warning Sponsored <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 css-x82yov" style="--Paper-shadow:0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)"><a title="Try Amazon today!" target="_blank" href="https://amzn.to/3C7FDwt"><div class="MuiBox-root css-0"><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh">Shop on Amazon today for unbeatable convenience, top deals, and an endless selection of products. Discover everything you need, from the latest tech to everyday essentials, all delivered quickly and securely. Don't miss out—experience hassle-free shopping at its best!</p><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh">Try Amazon today!</p></div></a></div> !!! **Target Audience** This guide is designed for a wide range of individuals interested in enhancing their NextJS authentication skills: - **NextJS Developers:** Developers seeking to elevate their NextJS development skills by mastering advanced authentication and authorization techniques. - **Web Security Specialists:** Aspiring web security specialists seeking to expand their knowledge of secure user authentication and authorization in NextJS applications. - **MongoDB Enthusiasts:** Enthusiasts eager to explore MongoDB's authentication capabilities and its integration with NextJS 14. **Embrace the Future of Secure NextJS Development** By embarking on this comprehensive journey, you will gain the necessary skills and knowledge to seamlessly implement authentication and role-based authorization within your NextJS 14 applications. This guide will empower you to: - **Effortlessly Set Up User Authentication:** Discover how to set up secure user authentication, ensuring a secure and personalized user experience. - **Implement Flawless Role-Based Access Control:** Implement role-based access control to manage user permissions, ensuring that users only access authorized application features. - **Harness NextJS 14, NextAuth, and MongoDB Adapter:** Leverage the power of NextJS 14, NextAuth, and MongoDB Adapter to create a smooth, secure, and scalable user authentication experience. **Enhance Your NextJS Skills** Whether you're a beginner or an experienced developer, this guide equips you with the tools and knowledge to effortlessly implement advanced authentication and authorization features in your NextJS projects. Level up your NextJS game and don't miss this opportunity to enhance your skills! > [Link to the repo can be found here](https://github.com/torver213/nextjs14-nextauth-nodeapi-yt) **Watch Now and Unlock Seamless Authentication** Embark on this journey to master NextAuth and MongoDB for secure authentication and role-based authorization in NextJS 14. Watch now and unlock the world of seamless authentication and role-based authorization in NextJS 14! Don't forget to like, subscribe, and share this knowledge with fellow developers! <iframe width="560" height="315" src="https://www.youtube.com/embed/JBo2DMegIxM?si=ojWz5x-1Iwy8FOF3" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> > Don't miss out—watch, subscribe, and share with your developer community!
auto deploy reactjs application on cpanel using github actions(ci/cd)
Setting up auto-deployment of your React.js app on cPanel using GitHub Actions brings efficiency and...
Setting up an automated deployment pipeline for your React.js application can save time and reduce the risk of human error when updating your live site. By leveraging GitHub Actions, you can establish a Continuous Integration and Continuous Deployment (CI/CD) workflow that pushes changes from GitHub to your cPanel-hosted application automatically. !!! info Sponsored <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 css-x82yov" style="--Paper-shadow:0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)"><a title="Checkout this unbeatable devices on Amazon" target="_blank" href="https://amzn.to/4efvtaq"><div class="MuiBox-root css-0"><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh">Looking for affordable devices and electronics to upgrade your tech space?</p><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh">Checkout this unbeatable devices on Amazon</p></div></a></div> !!! #### Prerequisites - **A GitHub Repository**: Your React.js application should be hosted on GitHub. - **cPanel Hosting Package**: Ensure your hosting plan supports Node.js or has access to SSH and a terminal. - **FTP/SFTP Credentials**: You’ll need your FTP/SFTP login details from your cPanel to set up the deployment process. #### Overview of the Process 1. **Create a GitHub Action Workflow**: Set up a YAML file to define the deployment pipeline. 2. **Connect GitHub to Your cPanel**: Use FTP or SFTP to transfer files securely. 3. **Configure cPanel for React.js**: Ensure the environment is ready to serve the built React.js files. 4. **Automate Deployment**: Every code change triggers GitHub Actions to build and deploy the app to cPanel. !!! abstract Sponsored <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 css-x82yov" style="--Paper-shadow:0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)"><a title="Try Amazon Devices & Accessories Today" target="_blank" href="https://amzn.to/4f7q9HH"><div class="MuiBox-root css-0"><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh">Discover the best of smart living with Amazon Devices & Accessories. From enhancing your home with Alexa-powered smart speakers and displays to optimizing your entertainment with Fire TV and Kindle e-readers, Amazon’s devices offer convenience, innovation, and seamless integration into your daily life. </p><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh">Try Amazon Devices & Accessories Today</p></div></a></div> !!! ### Step-by-Step Guide #### Step 1: Prepare Your React.js Application Ensure your React.js app is ready for deployment. This typically includes: - Having a production build script (`npm run build`). - Verifying all dependencies are up to date. #### Step 2: Set Up Your cPanel 1. **Create a Directory**: Log into your cPanel and navigate to the `public_html` folder or a subdirectory where you want your React app to be hosted. 2. **FTP/SFTP Credentials**: Obtain your FTP/SFTP credentials from cPanel (e.g., username, password, server address, and port). #### Step 3: Create a GitHub Actions Workflow 1. **Add a `.github/workflows/deploy.yml` File**: Create a `deploy.yml` file inside your GitHub repository to define the workflow. Here’s an example configuration: ```yaml on: push: branches: - main name: 🚀 Deploy website on push jobs: web-deploy: name: 🎉 Deploy runs-on: ubuntu-latest steps: - name: 🚚 Get latest code uses: actions/checkout@v3 - name: Use Node.js 16 uses: actions/setup-node@v2 with: node-version: '16' - name: 🔨 Build Project run: | npm install npm run build - name: 📂 Sync files uses: SamKirkland/FTP-Deploy-Action@v4.3.4 with: server: ${{ secrets.GIT_CPANEL_REACT_SERVER }} username: ${{ secrets.GIT_CPANEL_REACT_USER }} password: ${{ secrets.GIT_CPANEL_REACT_PWD }} protocol: ${{ secrets.GIT_CPANEL_REACT_PROTOCOL }} local-dir: ./build/ ``` > If you want to learn how to configure the above variables in github, there's a video at the end of this tutorial for a comprehensive step by step on how to accomplish that. 2. **Add Secrets to GitHub**: - Go to your GitHub repository settings. - Navigate to **Secrets and Variables** > **Actions**. - Add `GIT_CPANEL_REACT_SERVER`, `GIT_CPANEL_REACT_USER`, `GIT_CPANEL_REACT_PWD`, `GIT_CPANEL_REACT_PROTOCOL` as secrets with their respective values. #### Step 4: Trigger Your Workflow Once the workflow file is pushed to your repository, any changes pushed to the `main` branch will trigger the workflow. This will: - Checkout your code. - Install dependencies. - Build your React.js application. - Deploy the `build` folder to your cPanel using FTP. #### Step 5: Verify Your Deployment Navigate to your domain or subdomain to verify the deployment. Your React.js application should be live, reflecting the latest changes from GitHub. > [Click here for the full source code](https://github.com/torver213/youtube-react-cpanel) ### Benefits of This CI/CD Setup - **Automation**: Saves time by automatically deploying code on push, eliminating manual file transfers. - **Consistency**: Ensures the same build process every time, reducing deployment errors. - **Easy Updates**: Any code changes pushed to the branch will be reflected on the server automatically. ### Potential Challenges - **FTP/SFTP Security**: Ensure that your credentials are kept secure using GitHub Secrets. - **cPanel Limitations**: Shared hosting might have restrictions compared to cloud-based solutions. !!! abstract Sponsored <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 css-x82yov" style="--Paper-shadow:0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)"><a title="Try amazon computer devices today" target="_blank" href="https://amzn.to/40tIpX2"><div class="MuiBox-root css-0"><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh">Looking for the best coding laptops?</p><p class="MuiTypography-root MuiTypography-body2 css-bxmwoh">Try amazon computer devices today</p></div></a></div> !!! ### Conclusion Setting up auto-deployment of your React.js app on cPanel using GitHub Actions brings efficiency and consistency to your development workflow. While this solution is ideal for smaller-scale applications or projects on a budget, for larger projects, consider alternatives like dedicated cloud platforms for enhanced performance and scalability. #### Bonus: Watch the Video Tutorial If you're someone who prefers a visual walkthrough, check out the video below for a step-by-step guide: <iframe width="560" height="315" src="https://www.youtube.com/embed/x_GZpOGyJpg?si=4XZqxFGMqjuQALtN" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> Don't forget to like, comment, and subscribe for more tutorials!
Hosting your Next.js app on cPanel can be a practical solution, especially for smaller projects or personal sites. While it might lack some advanced features like serverless functions and automatic static optimization, it offers a cost-effective way to maintain control over your application.
Securing a Node.js REST API can be achieved by using Express Rate Limit to restrict the number of API calls a client can make within a specific timeframe, effectively preventing abuse, protecting server resources, and reducing the risk of denial-of-service (DoS) attacks.
To improve the performance of a Node.js application server, use compression to reduce data transfer size and caching to store frequently accessed data. Integrating compression middleware like `compression` decreases response times by compressing HTTP responses. Implementing server-side caching with tools such as `node-cache` or Redis and utilizing HTTP caching headers like `Cache-Control` and `ETag` further reduces server load and speeds up responses. These techniques collectively enhance the efficiency and responsiveness of the server.
how to host client react.js application on cpanel
Hosting a React.js app on cPanel is a cost-effective and straightforward option that utilizes existi...
In order to host your react.js app on cpanel, we will assume you have acquired a hosting package with cpanel accessible. In this article, we will be using namecheap shared hosting package but you can use any hosting plan. **Video Tutorial** If you are the visual type like me, go ahead and watch the video below. _Please don't forget to like, share, comment, subscribe and turn on notification as that will give me the motivation to do more awesome videos and tutorials like this._ <iframe width="560" height="315" src="https://www.youtube.com/embed/F0ORxJWZ_D8?si=HeiE4lHvOzfprA1c" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> ## Things to note before hosting your react.js app - Ensure your domain is linked to your hosting account. - If main domain is already in use, create a subdomain dedicated for this project. In this article we will be using **https://supablog.supatechie.ga** but go ahead and replace it with your domain or subdomain. Once you’ve all these ready, follow the instructions below; - Create a new directory called project on your desktop or in your drive. - If you don’t have a react.js app already, go ahead and open your command line prompt and navigate to the project directory and run ``` npx create-react-app@latest client ``` The above command will create a new react.js app with name client for you but if you already have one, go ahead and skip this step. - After the **client** app has been created, open the **project** directory in any code editor of your choice. - Within the **client** directory, open **public** directory and create a new file with the name **.htaccess** and copy & paste the configuration below and save your file. !!! attention Sponsored <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 css-x82yov" style="--Paper-shadow:0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)"><p class="MuiTypography-root MuiTypography-body1 css-fyswvn">Looking for affordable home appliances? Search no more</p><a title="Buy on Amazon Now" target="_blank" href="https://amzn.to/3YHqgUy">Buy on Amazon Now</a></div> !!! ``` <IfModule mod_rewrite.c> RewriteEngine On RewriteBase / RewriteRule ^index\.html$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-l RewriteRule . /index.html [L] </IfModule> ``` - Still within your **client** directory, open **package.json** file and add _“homepage”: “your_domain_url”_ key value pair, e.g ``` "name": "supablog", "version": "0.1.0", "private": true, "homepage": "https://supablog.supatechie.ga", ``` Save all the changes you have made. - Open your cmd and navigate to your **client** directory and run the command below to prepare the app for production. ```bash npm run build ``` - Once it’s done building assuming no error occurred, open your file explorer on your system and go to **project/client** directory and you should see **build** directory. Open the build directory and highlight all the directories and files and zip it. If you are on windows, you can simply install **WinRAR** in order to zip your files. - Next step is to open your browser and login to your cpanel, scroll to _Files _ section and click on **File Manager**. This will take you to the files directory. ![Cpanel File Manager](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9huym0965sqdd3tjlz5v.png) - If you’re using your main domain, go ahead and open **public_html** to host your app but if you created a subdomain, cpanel should automatically create a new empty directory with name of the subdomain for you in this case our directory will be called **supablog.supatechie.ga** ![File Manager supablog.supatechie.ga](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3452axbh8kogoh3nkpwo.png) - Open the directory and click on **upload ** at the top navigation bar ![cpanel upload button](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7o5no6vif7cm54nyulyj.png) - This should take you to an upload page. Click on the select file and it should open your system’s file explorer for you. Navigate to your _project/cliecnt/build/_ and select the **build.zip** file. ![cpanel upload files](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j9lhparx3zy8gzekik9y.png) - Once the zip file is uploaded, click on the link below to go back to your cpanel File Manager. - You will locate the **build.zip** over there, select the file and click on extract file on the top right. Your files will be extracted successfully - Open a new browser tab and type your domain name and the site should be opened successfully !!! note Sponsored <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 css-x82yov" style="--Paper-shadow:0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)"><p class="MuiTypography-root MuiTypography-body1 css-fyswvn">Looking for a platform to easily monetize your content?</p><a title="Try monetize today!" target="_blank" href="https://monetag.com/?ref_id=uawc">Try monetize today!</a></div> !!! Congratulations if you have made it this far. Now you have successfully hosted your react.js app on cpanel without losing any functionality. P.S _If you want a full tutorial on how to build a react.js and node.js express RESTful API from the scratch and host it on cpanel, please follow this my playlist on Youtube thank you._ <iframe width="560" height="315" src="https://www.youtube.com/embed/F0ORxJWZ_D8?si=HeiE4lHvOzfprA1c" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
Hosting a Next.js website on cPanel with Namecheap's shared hosting is a cost-effective alternative to platforms like Vercel. By exporting your Next.js site as static HTML, you can upload it to cPanel, eliminating the need for additional hosting fees. This method retains core Next.js features like optimized image handling and custom routing but lacks serverless functions and automatic static optimization. Ideal for static or minimally dynamic sites, this setup leverages your existing hosting plan and provides full control over file management and settings.
CORS (Cross-Origin Resource Sharing) is a security mechanism that allows client applications to request resources hosted on a server from a different origin (domain, scheme, or port). It extends the same-origin policy by defining rules for how browsers and servers can determine if a cross-origin request is safe. Typically, AJAX requests are limited to the same origin, but CORS enables controlled access to external resources like images, fonts, and APIs.
realtime data streaming using server-sent events(sse) with react.js and node.js
Real-time data streaming is essential for keeping users instantly informed of events. Traditional cl...
We live in a world where real-time data streaming has become paramount. Real-time data streaming has become a necessity in modern applications because it keeps users notified immediately an event happens. But most of the communication we see on the internet involves a client application making a request to the server which in turn processes the request and send back response to the client. This takes time to process and there are scenarios where a server needs to send data to the client without the client necessarily initiating a request. !!! success Sponsored <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 css-x82yov" style="--Paper-shadow:0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)"><p class="MuiTypography-root MuiTypography-body1 css-fyswvn">Checkout this affordable amazon products for amazing shopping experience</p><a title="Amazon Movers & Shakers" target="_blank" href="https://amzn.to/3Akqx6j">Amazon Movers & Shakers</a></div> !!! This could be done using long polling, websockets, webhooks or server-sent events. Examples of real-time applications include; instant messaging, notification system, online gaming, chat apps, videoconferencing, data streaming, sport updates, stock prices e.t.c. But our main focus in the article is Server-sent events. **Video Tutorial** _If you prefer to watch and learn an in-depth tutorial on how to implement server-sent events(SSEs) with react js and node js, here is a full video for you._ _Please don't forget to like, comment, subscribe to my youtube channel and share the video with your friends._ <iframe width="560" height="315" src="https://www.youtube.com/embed/d06PFSHfdzM?si=JDWFqN4IJ-ygMHVy" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> ## Different techniques for client-server communication Below are some of the techniques used for client server communication **Polling** is a technique where the application repeatedly polls data from the server and if you are familiar HTTP protocol, it involves request/response format. It is a traditional technique used by the vast majority of AJAX applications. The trade off with polling is that it creates greater HTTP overhead. !!! abstract Sponsored <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 css-x82yov" style="--Paper-shadow:0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)"><p class="MuiTypography-root MuiTypography-body1 css-fyswvn">Looking for the best coding and programming devices, check out this affordable products on amazon</p><a title="Amazon Movers & Shakers in Computers & Accessories" target="_blank" href="https://amzn.to/48qJocy">Amazon Movers & Shakers in Computers & Accessories</a></div> !!! **Long polling** is a technique in which if the server does not have the data available when a request is made from the client, the server holds the request open until data is available. The server responds when data becomes available, closes the connection and when the client receives the new data, it sends another request to the server again. This cycle is repeated endlessly until either of them closes the connection. The major drawback of this mechanism is once the server has sent the data; it cannot send further data until a new poll request arrives. **WebSockets** is a communication protocol that provides full-duplex bi-directional, communication channel over a single TCP connection. This mechanism creates a two-way connection between the server and the client i.e the server can send data to the client and client can send data to the server as well This is great for things like chat apps, instant messaging e.t.c. However, sometimes you need some updates from the server without waiting for the client to repeatedly initiate requests. This includes; friends' online status updates, newsfeeds e.t.c **Server-Sent Events** is an HTTP standard that enables a client application to automatically receive updates or event streams from the server once an initial connection has been established. It’s a server push technology that allows client apps to receive data transmission from the server via an HTTP connection and describes how servers can stream data to the client once an initial connection has been established. Server-sent events (SSEs) are unidirectional in nature i.e., only the server can push updates to client. SSE is commonly used to send automatic updates or continuous data streams to a browser client. The main difference between Server-Sent Events and long-polling is that SSEs are handled directly by the browser and the client app simply has to listen for messages. SSE contained in the JavaScript EventSource API in order to open a connection to the server to continue receiving event streams. In server-sent events, automatic updates are sent to client rather than pulled from the client. !!! warning Sponsored <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 css-x82yov" style="--Paper-shadow:0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)"><p class="MuiTypography-root MuiTypography-body1 css-fyswvn">Are you a movie enthusiast, this amazon collections will wow you. Try it out!.</p><a title="Amazon Movers & Shakers" target="_blank" href="https://amzn.to/3UtxeKg">Amazon Movers & Shakers</a></div> !!! ## Server-sent events VS Websockets **WebSockets** provide **bi-directional**, full-duplex communication. It creates a two-way channel where the client can send data to the server and the server can also send data to client. This enables a real-time communication in both directions. This makes it effective for cases like real-time chat apps, games etc. However, there are some scenarios where client apps don’t need to send data to server but only consumes from the server and this is where server-sent events(SSEs) comes in. In SSEs, the communication is **unidirectional** i.e., the server continuously pushed event streams to the client once an initial connection has been established. Examples include; real-time notification systems, sport updates, stock prices, status updates, newsfeed, cryptocurrency updates e.t.c **Server-sent Events implementation** Server sent server can be implemented both server side and client-side environment. **Client-side API** The SSE client API is contained in the **EventSource** object. When using SSE, the browser will generate an instance of **EventSource** first to initiate a connection to the server. In order to detect if a browser supports SSEs, use the code snippet below; ``` const url = "http://localhost:5000/stream" //url can be your server url if ('EventSource' in window) { let source = new EventSource(url) } ``` !!! info Sponsored <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 css-x82yov" style="--Paper-shadow:0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)"><p class="MuiTypography-root MuiTypography-body1 css-fyswvn">Get the latest cell phones and must-have accessories on Amazon! With top brands, exclusive deals, and fast delivery, it’s never been easier to stay connected and stylish. Find your perfect tech match today!</p><a title="Amazon Movers & Shakers in Cell Phones & Accessories" target="_blank" href="https://amzn.to/4fnDf3g">Amazon Movers & Shakers in Cell Phones & Accessories</a></div> !!! **Note:** The **URL** above can be in the same domain as the current **URL** of the application or it can be cross domain as well. When the URL passed to the **EventSource** constructor is an absolute URL, its origin (scheme, domain, port) must match that of the server. When a cross-domain is passed as the url, you can specify a second _options _ parameter with **withCredentials** property to indicate whether to send the cookie & auth headers altogether or not as shown below. ``` const url = "http://localhost:5000/stream" //url is your server url if ('EventSource' in window) { let source = new EventSource(url, {withCredentials: true}) } ``` **Eventsource object events** By default, there are three (3) events which include **message**, **open** and **error** to listen on. - The **open** event indicates a successful connection between the server and the client. - The **error** event handles an error connection between the server and the client. - The **message** event is used to listen on live stream data emitted by the server after a successful connection. SSEs are flexible enough that you can even define your own custom events on the server which you in turn listen on, on the client side. Below are the three (3) default event listeners with their callbacks. ``` source.addEventListener('message', function(e) { console.log(e.data); }, false); ``` ``` source.addEventListener('open', function(e) { // successful connection. }, false); ``` ``` source.addEventListener('error', function(e) { // error occurred }, false); ``` **EventSource object properties** Some of the properties of the **EventSource** instance include; - **readyState** e.g source.readyState - readyState value of 0 indicates connecting - readyState value of 1 indicates open - readyState value of 0 indicates closed - **url** e.g source.url returns connection url - **withCredentials** e.g source.withCredentials show whether or not **withCredentials** is true. **EventSource object methods** The **closed()** method can be called to close the connection e.g source.closed() **Server-side implementation** **SSE Data format** The SSE data sent by the server to the browser must be UTF-8 encoded text with the following HTTP header. ``` Content-Type: text/event-stream Cache-Control: no-cache Connection: keep-alive ``` The information sent each time consists of several messages, and each message is separated by **\n\n**. Each message is composed of several lines of code internally, and each line should be written as follows. [field]: value\n The above field can take the following four values. - **data ** indicates the payload to be sent. - **retry** indicates the reconnection time in seconds and it's optional - **event** can be a custom event e.g notification defaults to **message** when no event is passed - **id** indicates the id of the data to be sent and it's optional ``` const emitSSE= (res, id, data) =>{ res.write('id: ' + id + '\n'); res.write("data: " + data + '\n\n'); res.flush() } const handleSSE = (req, res) =>{ res.writeHead(200, { 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache', 'Connection': 'keep-alive' }); const id = (new Date()).toLocaleTimeString(); // Sends a SSE every 3 seconds on a single connection. setInterval(function() { emitSSE(res, id, (new Date()).toLocaleTimeString()); }, 3000); emitSSE(res, id, (new Date()).toLocaleTimeString()); } //use it app.get("/stream", handleSSE) ``` **Using Server-sent events with React.js and Node.js** Implementing server-sent events can be fairly simple but it gets confusing when you want target or send an event to a specific user as there is no clear way to exchange user data with the server. But in the video tutorial below; we have addressed the issues of sending global events as well as targeting specific users. In the video tutorial below, we are going to build and deploy a realtime twitter-like newsfeed using server-sent events(SSE) with react.js, node.js and mongodb from the scratch and deploy it on cpanel. This tutorial is for beginners and advanced programmers who wish to learn to implement the following; 1. How to implement SSE in react js and node js application 2. How to broadcast data to all users using server-sent events 3. How to send data to a specific or single user using server-sent events 4. How to implement LIKE button 5. API(Application Programming Interface) 6. React Hooks(useState, useContext, useReducer) 7. Hosting(Deployment) on cpanel **Resources & Demo** > [Get the code on github here](https://github.com/torver213/react-node-sse) **Summary** _Realtime data streaming has become a necessity in a standard modern application as this keeps your user notified of all the activities within your application. In this article, we discussed various techniques of client server communication and the need to go with server-sent events. Server-sent events(SSE) is a server push technology that enables a client to receive live stream updates from the server via a HTTP connection. It is lightweight and supported by most modern browsers and as a result, it's well suited for real-time automatic data stream from the server_ !!! attention Sponsored <div class="MuiPaper-root MuiPaper-elevation MuiPaper-rounded MuiPaper-elevation1 css-x82yov" style="--Paper-shadow:0px 2px 1px -1px rgba(0,0,0,0.2),0px 1px 1px 0px rgba(0,0,0,0.14),0px 1px 3px 0px rgba(0,0,0,0.12)"><p class="MuiTypography-root MuiTypography-body1 css-fyswvn">Upgrade your wardrobe with ease on Amazon! Discover the latest styles, unbeatable deals, and fast shipping—all from the comfort of home. Find your perfect fit today!</p><a title="Amazon Movers & Shakers" target="_blank" href="https://amzn.to/3C8QhDu">Amazon Movers & Shakers</a></div> !!! **Video Tutorial** If you want to watch and learn an in-depth tutorial on how to implement server-sent events(SSEs) with react js and node js, here is a video for you. _Please don't forget to like, comment, subscribe to my youtube channel and share the video with your friends._ <iframe width="560" height="315" src="https://www.youtube.com/embed/d06PFSHfdzM?si=JDWFqN4IJ-ygMHVy" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
Follow Us on Our Social Media Channels
Receive amazing technology tips directly from us once in a week.