<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mohamed Yamani</title>
    <description>The latest articles on DEV Community by Mohamed Yamani (@yamanidev).</description>
    <link>https://dev.to/yamanidev</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F680130%2F090d4653-f8a6-4180-adbc-1bcf78e1b05f.jpg</url>
      <title>DEV Community: Mohamed Yamani</title>
      <link>https://dev.to/yamanidev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yamanidev"/>
    <language>en</language>
    <item>
      <title>How to Deploy a Next.js Application to a VPS Using NGINX and PM2</title>
      <dc:creator>Mohamed Yamani</dc:creator>
      <pubDate>Sat, 02 Mar 2024 08:00:00 +0000</pubDate>
      <link>https://dev.to/yamanidev/how-to-deploy-a-nextjs-application-to-a-vps-using-nginx-and-pm2-4jfn</link>
      <guid>https://dev.to/yamanidev/how-to-deploy-a-nextjs-application-to-a-vps-using-nginx-and-pm2-4jfn</guid>
      <description>&lt;p&gt;This was originally published on my &lt;a href="https://mohamedyamani.com/blog/how-to-deploy-nextjs-application-to-vps-using-nginx-and-pm2/" rel="noopener noreferrer"&gt;blog&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In this guide I explain how to deploy your Next.js application to a VPS as well as the different parts of the process. If you're only looking for the NGINX configuration files, you can find them in this &lt;a href="https://gist.github.com/yamanidev/839d2ef90c2da03df892fdff50c4fb34" rel="noopener noreferrer"&gt;gist&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;If you find yourself in a situation (like I did) where your only deployment option for a Next.js application is to self-host on a VPS, this article is for you.&lt;/p&gt;

&lt;p&gt;This article does not promote self-hosting your Next.js applications, although I should write more on that in a separate article. It's a great learning experience to deal with servers directly (without the serverless abstraction).&lt;/p&gt;

&lt;p&gt;You need to be mindful that you can be limited by client/project requirements on what tools to use, especially for infrastructure. In which case, what do you do?&lt;/p&gt;

&lt;p&gt;Note: the Next.js application we will be deploying uses the Pages Router.&lt;/p&gt;

&lt;h2&gt;
  
  
  Assumptions
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;You've configured your domain name to point to your VPS' IP address.&lt;/li&gt;
&lt;li&gt;You've configured your SSH key(s) to access the VPS and to connect to GitHub.&lt;/li&gt;
&lt;li&gt;You're accessing the VPS with root privileges, so I don't need to use &lt;code&gt;sudo&lt;/code&gt; in the commands of this article.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is going to be as straightforward as your understanding of Next.js itself and servers in general.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next.js?
&lt;/h2&gt;

&lt;p&gt;You need to understand what it is your deploying to be able to deploy it.&lt;/p&gt;

&lt;p&gt;So what's Next.js? Well, it depends how you're using it.&lt;/p&gt;

&lt;p&gt;If you're using the framework to &lt;strong&gt;build an SPA&lt;/strong&gt; (not SSG), your application is essentially a bunch of &lt;strong&gt;static files&lt;/strong&gt; (HTML, CSS and JavaScript).&lt;/p&gt;

&lt;p&gt;However, if need SSR/SSG/ISR or any of these &lt;a href="https://nextjs.org/docs/pages/building-your-application/deploying/static-exports#unsupported-features" rel="noopener noreferrer"&gt;features&lt;/a&gt;, your Next.js application needs to run as a &lt;strong&gt;Node server&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deployment
&lt;/h2&gt;

&lt;p&gt;Given that our Next.js application is essentially different for different contexts, it's only natural that the deployment of it will also be different.&lt;/p&gt;

&lt;h3&gt;
  
  
  Deploying static files (static export)
&lt;/h3&gt;

&lt;p&gt;A fundamental concept is in play here. Our application is just a bunch of static files, how do we deploy them?&lt;/p&gt;

&lt;p&gt;In order to deliver these files to the client (GUI browser, CLI browser -&lt;a href="https://en.wikipedia.org/wiki/Lynx_(web_browser)" rel="noopener noreferrer"&gt;Lynx&lt;/a&gt; for eg-, &lt;code&gt;curl&lt;/code&gt;... whatever is requesting the resources), we need a web server. It does not happen magically, everything is deliberate.&lt;/p&gt;

&lt;p&gt;(This will apply to any kind of file you want to serve.)&lt;/p&gt;

&lt;p&gt;We'll be using &lt;a href="https://nginx.org/en/" rel="noopener noreferrer"&gt;NGINX&lt;/a&gt; as a web server in this guide, so make sure to install it on your VPS if it's not already installed: &lt;a href="https://www.nginx.com/resources/wiki/start/topics/tutorials/install/" rel="noopener noreferrer"&gt;NGINX installation guide&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In summary, this is how we'll use NGINX:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdye80e9si8gfyqwmlvrm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdye80e9si8gfyqwmlvrm.png" alt="Flow of serving static files with NGINX over HTTP" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After you clone your Next.js project and build it for a static export, an &lt;code&gt;out/&lt;/code&gt; directory will be generated for the static build (at the time of writing. The folder name might change in the future).&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;out/&lt;/code&gt; folder contains the static files of our Next.js SPA application. In order for NGINX to serve files, it needs to look into a directory for them. We're going to place our project(s) in the &lt;code&gt;/srv&lt;/code&gt; directory.&lt;/p&gt;

&lt;p&gt;You'll often see websites placed on directories like &lt;code&gt;/var/www/&lt;/code&gt; or &lt;code&gt;/var/www/html/&lt;/code&gt; etc. It usually doesn't matter where you place your project, especially if you're only hosting one website.&lt;/p&gt;

&lt;p&gt;According to the &lt;a href="https://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard" rel="noopener noreferrer"&gt;FHS&lt;/a&gt;, &lt;code&gt;/srv&lt;/code&gt; is used for &lt;em&gt;site-specific data which is served by this system.&lt;/em&gt; I like to stick to the &lt;a href="https://refspecs.linuxfoundation.org/FHS_3.0/fhs/ch03s17.html" rel="noopener noreferrer"&gt;standard&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;After you &lt;code&gt;cd&lt;/code&gt; into your Next.js project, we'll copy the generated &lt;code&gt;out/&lt;/code&gt; directory into &lt;code&gt;/srv&lt;/code&gt; with the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;cp -r out /srv/&lt;span class="nt"&gt;&amp;lt;project&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In addition to copying the &lt;code&gt;out/&lt;/code&gt; directory, the command will rename it to whatever you replaced &lt;code&gt;&amp;lt;project name&amp;gt;&lt;/code&gt; with.&lt;/p&gt;

&lt;h4&gt;
  
  
  Configuring NGINX to serve static files over HTTP
&lt;/h4&gt;

&lt;p&gt;As stated earlier, nothing happens magically, so in order to get the behavior above, we need to configure NGINX accordingly. For simplicity's sake, we're going to only edit the default NGINX configuration file located at &lt;code&gt;/etc/nginx/sites-available/default&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Once you open that file with the text editor of your choice, you'll see some pre-existing configuration, we're going to be interested in the &lt;code&gt;server&lt;/code&gt; block. The configuration should look something like this, minus a few comments:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;&lt;span class="k"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt; &lt;span class="s"&gt;default_server&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="s"&gt;[::]:80&lt;/span&gt; &lt;span class="s"&gt;default_server&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;# SSL configuration&lt;/span&gt;
    &lt;span class="c1"&gt;#&lt;/span&gt;
    &lt;span class="c1"&gt;# listen 443 ssl default_server;&lt;/span&gt;
    &lt;span class="c1"&gt;# listen [::]:443 ssl default_server;&lt;/span&gt;
    &lt;span class="c1"&gt;#&lt;/span&gt;
    &lt;span class="c1"&gt;# Note: You should disable gzip for SSL traffic.&lt;/span&gt;
    &lt;span class="c1"&gt;# See: https://bugs.debian.org/773332&lt;/span&gt;
    &lt;span class="c1"&gt;#&lt;/span&gt;
    &lt;span class="c1"&gt;# Read up on ssl_ciphers to ensure a secure configuration.&lt;/span&gt;
    &lt;span class="c1"&gt;# See: https://bugs.debian.org/765782&lt;/span&gt;
    &lt;span class="c1"&gt;#&lt;/span&gt;
    &lt;span class="c1"&gt;# Self signed certs generated by the ssl-cert package&lt;/span&gt;
    &lt;span class="c1"&gt;# Don't use them in a production server!&lt;/span&gt;
    &lt;span class="c1"&gt;#&lt;/span&gt;
    &lt;span class="c1"&gt;# include snippets/snakeoil.conf;&lt;/span&gt;

    &lt;span class="kn"&gt;root&lt;/span&gt; &lt;span class="n"&gt;/var/www/html&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kn"&gt;index&lt;/span&gt; &lt;span class="s"&gt;index.html&lt;/span&gt; &lt;span class="s"&gt;index.htm&lt;/span&gt; &lt;span class="s"&gt;index.nginx-debian.html&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kn"&gt;server_name&lt;/span&gt; &lt;span class="s"&gt;_&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="n"&gt;/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;# First attempt to serve request as file, then&lt;/span&gt;
        &lt;span class="c1"&gt;# as directory, then fall back to displaying a 404.&lt;/span&gt;
        &lt;span class="kn"&gt;try_files&lt;/span&gt; &lt;span class="nv"&gt;$uri&lt;/span&gt; &lt;span class="nv"&gt;$uri&lt;/span&gt;&lt;span class="n"&gt;/&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Even if you've never used NGINX before, you can make an educated guess what the configuration does.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It's listening on port 80, which is the default port number for HTTP traffic.&lt;/li&gt;
&lt;li&gt;It sets a root directory &lt;code&gt;/var/www/html&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;It serves as entry point one of these files (in this order) &lt;code&gt;index.html&lt;/code&gt;, &lt;code&gt;index.htm&lt;/code&gt;, &lt;code&gt;index.nginx-debian.html&lt;/code&gt;. Fun fact, the reason &lt;code&gt;.htm&lt;/code&gt; is a valid HTML extension is due to limitations in some systems that accept at most 3 characters for filename extensions.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;location&lt;/code&gt; block seems to serve the rest of the static files if found, otherwise return a 404 status code, as the comment explains.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's fix it up to serve our Next.js project. Change the &lt;code&gt;root&lt;/code&gt; directive to point to our project's build:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;root /srv/&amp;lt;project name&amp;gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Change the &lt;code&gt;server_name&lt;/code&gt; directive to use your domain name:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;&lt;span class="k"&gt;server_name&lt;/span&gt; &lt;span class="s"&gt;example.com&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Change the &lt;code&gt;try_files&lt;/code&gt; directive to this, so that when a path is requested, an HTML file is returned with the same name if it exists.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;&lt;span class="k"&gt;try_files&lt;/span&gt; &lt;span class="nv"&gt;$uri&lt;/span&gt;&lt;span class="s"&gt;.html&lt;/span&gt; &lt;span class="nv"&gt;$uri&lt;/span&gt; &lt;span class="nv"&gt;$uri&lt;/span&gt;&lt;span class="n"&gt;/&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To check if your NGINX configuration is correct in terms of syntax, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nginx &lt;span class="nt"&gt;-t&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we must restart the NGINX service. Make sure to do this after any changes you make to the configuration file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;systemctl restart nginx.service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your static Next.js website should be accessible now. Let's test it out.&lt;/p&gt;

&lt;p&gt;To check if NGINX is serving files correctly, run the following command. This should return the &lt;code&gt;index.html&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl localhost
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If it doesn't:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Check if NGINX is running with &lt;code&gt;systemctl status nginx.service&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Check if the path you provided in the &lt;code&gt;root&lt;/code&gt; directive may be incorect.&lt;/li&gt;
&lt;li&gt;Make sure the path you provided in &lt;code&gt;root&lt;/code&gt; directive exists and contains your static files.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's test out the website using the domain name. Keep in mind that we're still using HTTP.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl http://example.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the command above does not return the &lt;code&gt;index.html&lt;/code&gt;, make sure that you configured your domain name's DNS properly to point to the VPS' IP address.&lt;/p&gt;

&lt;p&gt;The reason I started with HTTP configuration is to decrease the complexity and the number of factors that come to play with NGINX. Hopefully you've managed to get it setup successfully.&lt;/p&gt;

&lt;p&gt;Now it's time to get HTTPS working.&lt;/p&gt;

&lt;h4&gt;
  
  
  Configuring NGINX to serve static files over HTTPS
&lt;/h4&gt;

&lt;p&gt;Why? Because you don't want your users to use your website on top of an insecure protocol (HTTP), especially if you're dealing with sensitive data. Plus, it's nice to have an SSL certificate. Feel free to read &lt;a href="https://www.cloudflare.com/learning/ssl/why-use-https/" rel="noopener noreferrer"&gt;Why Use HTTPS&lt;/a&gt; by Cloudflare.&lt;/p&gt;

&lt;p&gt;What changes do you reckon we should make to the NGINX configuration to use HTTPS?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It's a different protocol, so a different kind of traffic.&lt;/li&gt;
&lt;li&gt;It uses SSL/TLS, so we need to setup certificates and private keys.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To handle the above, we'll use &lt;a href="https://certbot.eff.org/" rel="noopener noreferrer"&gt;Certbot&lt;/a&gt; which is a free utility that generates SSL certificates and configures HTTPS for you.&lt;/p&gt;

&lt;p&gt;Install it on your VPS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;certbot python3-certbot-nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we'll let Certbot do its magic!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;certbot &lt;span class="nt"&gt;--nginx&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; example.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll be prompted with a couple of questions, and once you answer accordingly, Certbot should generate your SSL certificate as well as configure NGINX for you.&lt;/p&gt;

&lt;p&gt;Once you open &lt;code&gt;/etc/nginx/sites-available/default&lt;/code&gt;, you'll see that the configuration Certbot added will be followed with &lt;code&gt;# managed by Certbot&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here are some of the things that Certbot adds to your NGINX configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;&lt;span class="k"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;443&lt;/span&gt; &lt;span class="s"&gt;ssl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;ssl_certificate&lt;/span&gt; &lt;span class="n"&gt;/etc/letsencrypt/live/example.com/fullchain.pem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;ssl_certificate_key&lt;/span&gt; &lt;span class="n"&gt;/etc/letsencrypt/live/example.com/privkey.pem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;include&lt;/span&gt; &lt;span class="n"&gt;/etc/letsencrypt/options-ssl-nginx.conf&lt;/span&gt;;
&lt;span class="k"&gt;ssl_dhparam&lt;/span&gt; &lt;span class="n"&gt;/etc/letsencrypt/ssl-dhparams.pem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These enables your NGINX server to listen to traffic on the port number 443 which is the default one for HTTPS traffic. Additionally this links to the generated SSL certificate and private keys.&lt;/p&gt;

&lt;p&gt;Certbot may also add this to your configuration, which listens on port 80 (for HTTP traffic) and redirects it to HTTPS, enforcing a more secure communication, otherwise return a 404 error status code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;&lt;span class="k"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;if&lt;/span&gt; &lt;span class="s"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$host&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;example.com)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kn"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;301&lt;/span&gt; &lt;span class="s"&gt;https://&lt;/span&gt;&lt;span class="nv"&gt;$host$request_uri&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;# managed by Certbot&lt;/span&gt;

    &lt;span class="kn"&gt;server_name&lt;/span&gt; &lt;span class="s"&gt;example.com&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;# managed by Certbot&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Deploying a Next.js server
&lt;/h3&gt;

&lt;p&gt;This is for projects that require SSR, SSG, ISR, or any of these &lt;a href="https://nextjs.org/docs/pages/building-your-application/deploying/static-exports#unsupported-features" rel="noopener noreferrer"&gt;features&lt;/a&gt;. As I mentioned earlier, now your Next.js needs to step up to a Node server to fulfill your requirements.&lt;/p&gt;

&lt;p&gt;An illustration of the deployment:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F304hhmclz5az8btbqdov.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F304hhmclz5az8btbqdov.png" alt="Using NGINX as a reverse proxy for the Next.js server" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To keep things simple, this time we'll clone our Next.js repository to &lt;code&gt;/srv&lt;/code&gt; directory. To run a production build of Next.js application, we don't require all the content of the project, but we'll keep them nevertheless.&lt;/p&gt;

&lt;p&gt;After you build your project, run the &lt;code&gt;next start&lt;/code&gt; script with whatever package manager you're using. You should be able to get back an HTML file when you &lt;code&gt;curl localhost:3000&lt;/code&gt; (or whatever port you configured). Once you've confirmed that your Next.js application runs successfully, stop it.&lt;/p&gt;

&lt;h4&gt;
  
  
  Running Node.js applications in production
&lt;/h4&gt;

&lt;p&gt;In a production environment, it's unwise to assume your server applications will continue running ad infinitum. Many things can go wrong which result in shutting down your applications:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Runtime errors may stop the server application from running.&lt;/li&gt;
&lt;li&gt;As part of maintenance procedures, your hosting provider may restart your VPS.&lt;/li&gt;
&lt;li&gt;Your server may catch fire, or experience an electric outage. Shit happens.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Bottom line is, your application must tolerate this kind of situations, by restarting when it shuts down, and by running on startup after system reboots etc.&lt;/p&gt;

&lt;p&gt;A popular tool for the job is &lt;a href="https://pm2.keymetrics.io/" rel="noopener noreferrer"&gt;PM2&lt;/a&gt;, which is a process manager for your Node.js applications.&lt;/p&gt;

&lt;p&gt;If you're using npm, install it globally with the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; pm2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the installation was successful, this command should return PM2's version:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pm2 &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After you &lt;code&gt;cd&lt;/code&gt; into your project's directory, run your Next.js application through PM2 with the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pm2 start npm &lt;span class="nt"&gt;--name&lt;/span&gt; &amp;lt;application name&amp;gt; &lt;span class="nt"&gt;--&lt;/span&gt; start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Replace &lt;code&gt;npm&lt;/code&gt; with whatever package manager you're using.&lt;/li&gt;
&lt;li&gt;The double dash &lt;code&gt;--&lt;/code&gt; indicates the end of the options/arguments list of a command, so that &lt;code&gt;start&lt;/code&gt; is considered an argument for &lt;code&gt;npm&lt;/code&gt; and not &lt;code&gt;pm2&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can check if the Node.js process is running with &lt;code&gt;pm2 status&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In order to run your Node.js applications on startup, PM2 itself must be running, in order to do that, run this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pm2 startup
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This ensures that PM2 runs on system startup.&lt;/p&gt;

&lt;p&gt;Similarly, run this command so that PM2 registers the application and run it on startup:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pm2 save
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can read more about this this in &lt;a href="https://pm2.keymetrics.io/docs/usage/startup/" rel="noopener noreferrer"&gt;PM2's documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Configuration NGINX as a reverse proxy
&lt;/h4&gt;

&lt;p&gt;As illustrated in the image above, NGINX will "forward" the requests it receives to the Next.js application (which is a Node.js server) and returns to the client whatever Next.js returns, acting as an intermediary. This is the basic functionality of a proxy.&lt;/p&gt;

&lt;p&gt;Open the configuration file &lt;code&gt;/etc/nginx/sites-available/default&lt;/code&gt;, and replace it with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;&lt;span class="k"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;server_name&lt;/span&gt; &lt;span class="s"&gt;example.com&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="n"&gt;/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;X-Forwarded-For&lt;/span&gt; &lt;span class="nv"&gt;$proxy_add_x_forwarded_for&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;X-Real-IP&lt;/span&gt; &lt;span class="nv"&gt;$remote_addr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;Host&lt;/span&gt; &lt;span class="nv"&gt;$http_host&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kn"&gt;proxy_http_version&lt;/span&gt; &lt;span class="mf"&gt;1.1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;Upgrade&lt;/span&gt; &lt;span class="nv"&gt;$http_upgrade&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;Connection&lt;/span&gt; &lt;span class="s"&gt;"upgrade"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kn"&gt;proxy_pass&lt;/span&gt; &lt;span class="s"&gt;http://localhost:3000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_redirect&lt;/span&gt; &lt;span class="no"&gt;off&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_read_timeout&lt;/span&gt; &lt;span class="s"&gt;240s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;443&lt;/span&gt; &lt;span class="s"&gt;ssl&lt;/span&gt; &lt;span class="s"&gt;default_server&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="s"&gt;[::]:443&lt;/span&gt; &lt;span class="s"&gt;ssl&lt;/span&gt; &lt;span class="s"&gt;default_server&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For HTTPS configuration, go through the process mentioned above with Certbot.&lt;/p&gt;




&lt;h2&gt;
  
  
  Closing thoughts
&lt;/h2&gt;

&lt;p&gt;A couple of weeks ago, I was struggling with this deployment for a client. I never really understood NGINX, because I never worked with it directly before. However I am very glad I was presented with this opportunity!&lt;/p&gt;

&lt;p&gt;It took me an entire day to debug its configuration and understand what the directives are doing to get the reverse proxy working. What can I say, I am a masochist, so I enjoy this.&lt;/p&gt;

&lt;p&gt;I hope you benefited from it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stay in touch
&lt;/h2&gt;

&lt;p&gt;If you'd like to stay updated with my blog, reach out, or see what I am up to, you can find me on &lt;a href="https://twitter.com/yamanidev" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thumbnail picture by &lt;a href="https://unsplash.com/@aronvisuals?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" rel="noopener noreferrer"&gt;Aron Visuals&lt;/a&gt; on &lt;a href="https://unsplash.com/photos/light-decorations-in-dark-area-bZZp1PmHI0E?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>nginx</category>
      <category>node</category>
      <category>deployment</category>
    </item>
    <item>
      <title>My First Experience Giving a Talk @Devfest El Bayadh 2023</title>
      <dc:creator>Mohamed Yamani</dc:creator>
      <pubDate>Wed, 24 Jan 2024 09:42:53 +0000</pubDate>
      <link>https://dev.to/yamanidev/my-first-experience-giving-a-talk-devfest-el-bayadh-2023-3dm3</link>
      <guid>https://dev.to/yamanidev/my-first-experience-giving-a-talk-devfest-el-bayadh-2023-3dm3</guid>
      <description>&lt;p&gt;Disclaimer: I take you through my thought process as I was preparing for my first talk. This is more personal, so you might not get any value from reading this. It's something to document about my journey, a piece I know I'd love to read in the future.&lt;/p&gt;

&lt;h2&gt;
  
  
  Context
&lt;/h2&gt;

&lt;p&gt;It was during my final Master's exams that I was contacted by a member of GDG El Bayadh (Google Developer Groups) asking if I am interested in giving/delivering a talk for their DevFest annual event on the 23rd December.&lt;/p&gt;

&lt;p&gt;FYI, El Bayadh is a small city in Algeria where nothing happens.&lt;/p&gt;

&lt;p&gt;I was pretty stressed at the time, which is interesting, because I am not the kind that ever got stressed over exams before. But this time, I was.&lt;/p&gt;

&lt;p&gt;We had 12 exams to go through, thankfully one exam a day. It however spanned across 3 weeks in total (don't ask me how). It was a marathon to cram for every class the night before.&lt;/p&gt;

&lt;p&gt;We'd finish exams on the 20th, that's 3 days for preparation (minus 1 to travel back El Bayadh).&lt;/p&gt;

&lt;p&gt;So given the masochist that I am, I accepted. And now I need to figure out what to talk about.&lt;/p&gt;

&lt;h2&gt;
  
  
  Realization and struggle
&lt;/h2&gt;

&lt;p&gt;But wait, what the hell do I know well enough to give a talk about?! My mind was blank.&lt;/p&gt;

&lt;p&gt;What do I even do? I freelance as a front end developer, but I am not sure what topic to talk about that would be valuable to the audience. Wait, I completely forgot about the audience...&lt;/p&gt;

&lt;p&gt;I've given presentations in the past academically, but it's always to people that were either paid (professors) or forced (students) to be there. But this time it's different. People will come out of interest and/or curiosity.&lt;/p&gt;

&lt;p&gt;That changes the dynamics.&lt;/p&gt;

&lt;p&gt;After asking the organizers about the demographics of the audience they're expecting, they said they're mostly university students from different backgrounds, as well as high schoolers. So I interpreted this as people that are interested in tech and/or beginners in development.&lt;/p&gt;

&lt;p&gt;That ended up being a correct interpretation.&lt;/p&gt;

&lt;p&gt;I got the idea to talk about technical writing, which was suggested to me too by some of my friends, but then I discarded it. I found it hypocritical to talk about something I failed to commit to. I've been writing sporadically over the last 3 years, and I only had ~11k views in total.&lt;/p&gt;

&lt;p&gt;Then I recognized that I deal with this problem occasionally when I want to publish an article too, seeing myself as not good enough to share my thoughts/experiences or to try to explain a concept.&lt;/p&gt;

&lt;p&gt;The way I resolve this is by mainly reminding myself that no matter how bad I think I am or how much I suck, there's surely someone that's worse out there, someone who's just starting their journey for example. That's my target audience. There's a high chance they'd find value in what I say... or so I'd like to think.&lt;/p&gt;

&lt;p&gt;So I reverted back to the idea of technical writing, it seems to have a low barrier of entry, and includes a wide range of disciplines, which suits the audience.&lt;/p&gt;

&lt;h2&gt;
  
  
  Preparation
&lt;/h2&gt;

&lt;p&gt;I started preparing for it the eve of the talk.&lt;/p&gt;

&lt;p&gt;I decided to give the talk in Algerian dialect. I wanted it to be more accessible to the crowd. While I would have preferred English to encourage youngsters to learn it more, it was not my objective for this talk.&lt;/p&gt;

&lt;p&gt;I never scripted my presentations before, I hated preparing for them too. I like to improvise, it has always served me well.&lt;/p&gt;

&lt;p&gt;But this time, I was not sure. It seemed to me that it would be unjust if I spoke nonsense to an audience that actually wanted to attend, especially since the talks are 20min long.&lt;/p&gt;

&lt;p&gt;So I started scribbling here and there.&lt;/p&gt;

&lt;h2&gt;
  
  
  The day of the talk
&lt;/h2&gt;

&lt;p&gt;My talk was the first one, I liked that. It wouldn't be a problem to set the bar low, because I am the first, and I could get done with it and focus on the other talks afterwards, instead of thinking about mine.&lt;/p&gt;

&lt;p&gt;The event was planned to start at 8h30 AM. I was there at ~7h30, sitting in front of the stage, waiting. My heart was racing, and I felt sick in my stomach. Very sick. Time was not passing by.&lt;/p&gt;

&lt;p&gt;Eventually, the event started after 9AM, and I was up.&lt;/p&gt;

&lt;p&gt;Thankfully, the moment I stood in front of the crowd, set up the presentation, I was back to normal. I was myself again.&lt;/p&gt;

&lt;p&gt;It went smoothly. I communicated the ideas I wanted to, and 18 minutes later, I was done.&lt;/p&gt;

&lt;h2&gt;
  
  
  Review
&lt;/h2&gt;

&lt;p&gt;I couldn't tell how the audience took it, but there was one guy who seemed interested that approached me during the coffee break with questions, which lead to a cool discussion.&lt;/p&gt;

&lt;p&gt;To me, it takes only one person to benefit from what I share to consider myself successful at it. I'd like to think I was this time.&lt;/p&gt;

&lt;p&gt;I am very happy that I got to meet cool people that I knew from the internet (yes. they're real): &lt;a href="https://twitter.com/karimkos" rel="noopener noreferrer"&gt;Karim&lt;/a&gt; and &lt;a href="https://twitter.com/HouariZegai" rel="noopener noreferrer"&gt;Houari&lt;/a&gt;. It was a pleasure!&lt;/p&gt;

&lt;p&gt;You also get some free photoshoots, and if you don't usually make weird faces, you get to use them. Unlike myself:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F567h02zlkw9l6ik0vpu8.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F567h02zlkw9l6ik0vpu8.jpg" alt="picture of myself making a weird face giving the talk with a slide titled " width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Follow my journey on Twitter
&lt;/h2&gt;

&lt;p&gt;You can find me on Twitter &lt;a href="https://twitter.com/yamanidev" rel="noopener noreferrer"&gt;@yamanidev&lt;/a&gt; where I am most active, documenting my journey and sharing what I learn about software engineering and tech in general.&lt;/p&gt;

&lt;p&gt;And lastly,&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;don't forget to touch some grass.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Take care!&lt;/p&gt;

</description>
      <category>google</category>
      <category>devfest</category>
      <category>personal</category>
      <category>talk</category>
    </item>
    <item>
      <title>Let's Understand CSS: Inheritance</title>
      <dc:creator>Mohamed Yamani</dc:creator>
      <pubDate>Fri, 20 Oct 2023 08:00:00 +0000</pubDate>
      <link>https://dev.to/yamanidev/lets-understand-css-inheritance-3gjn</link>
      <guid>https://dev.to/yamanidev/lets-understand-css-inheritance-3gjn</guid>
      <description>&lt;p&gt;Most CSS bugs come from conflicting styles which most people solve by slapping the notorious &lt;code&gt;!important&lt;/code&gt; at them, or by resorting to inline styles instead.&lt;/p&gt;

&lt;p&gt;The only fix to this is by understanding how CSS deals with conflicting rules, and how to use it to your advantage. This mostly includes 3 fundamental concepts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cascade.&lt;/li&gt;
&lt;li&gt;Specificity.&lt;/li&gt;
&lt;li&gt;Inheritance.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this article, I'll explain the last concept.&lt;/p&gt;

&lt;p&gt;Another equally important concept is the Box Model which I wrote about &lt;a href="https://mohamedyamani.com/blog/understanding-the-box-model-in-css/" rel="noopener noreferrer"&gt;2 years ago&lt;/a&gt;, that should explain why I describe myself as &lt;em&gt;sometimes a blogger&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;I'll be writing more often on fundamental CSS concepts that must be understood for smooth sailing with CSS, otherwise you'll relate to the memes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu6bpo0a1ji1k6bqs9dlm.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu6bpo0a1ji1k6bqs9dlm.jpg" alt="developer meme: hates to write CSS but still won't learn it" width="576" height="867"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you're someone that doesn't struggle with reading MDN docs, I recommend you skip this article to read the MDN one and wrap up inheritance in a few minutes: &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Inheritance" rel="noopener noreferrer"&gt;Inheritance MDN link&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you wish to stick around, buckle up.&lt;/p&gt;




&lt;p&gt;One of the best ways to learn about tech stuff is by thinking about how to build them yourself. What would be the process like? What decisions and compromises will you make to achieve X?&lt;/p&gt;

&lt;p&gt;Even if you're not able to answer these questions -understandably so-, they remain interesting questions to ask and find answers to.&lt;/p&gt;

&lt;p&gt;Shifting you thinking to how to build a tool will give you a chance to understand why certain things of behave the way they do, why they were built the way they were etc.&lt;/p&gt;

&lt;p&gt;Keeping in mind the properties you know and putting all your CSS knowledge aside, how do you think styling would be like?&lt;/p&gt;

&lt;p&gt;How's the architecture of styling web pages like?&lt;/p&gt;

&lt;p&gt;The way I see it, it will be very explicit and verbose.&lt;/p&gt;

&lt;p&gt;Since styling like this is not an option,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;ul&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"cool-list"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;banana&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;monkey&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;idk&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.cool-list&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;700&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;it has to be something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"not-so-cool-li"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;banana&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"not-so-cool-li"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;monkey&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"not-so-cool-li"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;idk&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.not-so-cool-li&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;700&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It would be a nightmare write and worse to maintain. Not so cool indeed.&lt;/p&gt;

&lt;p&gt;This is why inheritance was implemented. To make styling web pages compact and clean.&lt;/p&gt;

&lt;p&gt;Instead of having to style each HTML element separately, you can style a parent and the styles will get applied to its children &lt;strong&gt;at all nested levels&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;body&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"cool-body"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;main&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;header&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Some cool title I bet&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/header&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Bla bla bla &lt;span class="nt"&gt;&amp;lt;span&amp;gt;&lt;/span&gt;special bla bla&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/main&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.cool-body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;700&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Quick reminder:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Regardless of the nesting level of, if element A is in any shape contained inside of element B, then element A is a child of element B.&lt;/li&gt;
&lt;li&gt;The level of nesting is what determines if a child is a direct or an indirect one. If it's only nested one level deep, it's a direct child, otherwise it's an indirect one.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt; is a direct child of &lt;code&gt;&amp;lt;header&amp;gt;&lt;/code&gt; and an indirect child to &lt;code&gt;&amp;lt;main&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt; is a direct child of &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt; and an indirect child to &lt;code&gt;&amp;lt;main&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All of the children of &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; will &lt;em&gt;inherit&lt;/em&gt; the style declarations of the class &lt;code&gt;cool-body&lt;/code&gt;. i.e, everything will look tedious.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;p&gt;So what happens when different parents have conflicting style declarations? The conflict being having different values for the same CSS property.&lt;/p&gt;

&lt;p&gt;One of them must be picked of course.&lt;/p&gt;

&lt;p&gt;The algorithm to pick the inherited styles is pretty straightforward: we pick the styles of the closest parent. And since the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Document_object_model/Using_the_Document_Object_Model#what_is_a_dom_tree" rel="noopener noreferrer"&gt;DOM&lt;/a&gt; is a tree data structure, it's easy to do that.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;main&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"cool-main"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;header&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"cool-header"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Some cool title I bet&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/header&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Bla bla bla &lt;span class="nt"&gt;&amp;lt;span&amp;gt;&lt;/span&gt;special bla bla&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/main&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.cool-main&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;black&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.cool-header&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt; will take take &lt;code&gt;cool-header&lt;/code&gt;'s style because it's the closest parent.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt; will take &lt;code&gt;cool-main&lt;/code&gt;'s style because it's the closest parent.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt; will take &lt;code&gt;cool-main&lt;/code&gt;'s style because it's the closest parent.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thankfully, not all properties are inherited. Can you imagine passing down properties like &lt;code&gt;width&lt;/code&gt;, &lt;code&gt;display&lt;/code&gt;, &lt;code&gt;border&lt;/code&gt; etc?&lt;/p&gt;

&lt;p&gt;Most of the inherited properties are typography related, with some other ones you've never heard of. You can find the list of these properties in this &lt;a href="https://stackoverflow.com/a/5612360/14034906" rel="noopener noreferrer"&gt;Stack Overflow answer&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;Hope you learned something!&lt;/p&gt;

&lt;p&gt;Don't relate to CSS memes.&lt;/p&gt;

&lt;p&gt;Thumbnail by &lt;a href="https://unsplash.com/@jrkorpa?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" rel="noopener noreferrer"&gt;Jr Korpa&lt;/a&gt; on &lt;a href="https://unsplash.com/photos/oOqNQCIlt94?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

</description>
      <category>html</category>
      <category>css</category>
      <category>beginners</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Linux Fundamentals: File Permissions and Ownership</title>
      <dc:creator>Mohamed Yamani</dc:creator>
      <pubDate>Fri, 22 Sep 2023 08:00:00 +0000</pubDate>
      <link>https://dev.to/yamanidev/linux-fundamentals-file-permissions-and-ownership-179g</link>
      <guid>https://dev.to/yamanidev/linux-fundamentals-file-permissions-and-ownership-179g</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published at&lt;/em&gt; &lt;a href="https://mohamedyamani.com/blog/linux-fundamentals-file-permissions-and-ownership" rel="noopener noreferrer"&gt;&lt;em&gt;https://mohamedyamani.com&lt;/em&gt;&lt;/a&gt; &lt;em&gt;on September 19, 2023.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In my last article &lt;a href="https://mohamedyamani.com/blog/linux-fundamentals-explaining-the-ls-command-and-beyond" rel="noopener noreferrer"&gt;Explaining the ls command and beyond&lt;/a&gt;, I broke down the &lt;code&gt;ls&lt;/code&gt; command, how to interpret the output, and introduced some command line concepts. It was quite the jargon, and to some of you, it was unfamiliar.&lt;/p&gt;

&lt;p&gt;As such, I'll dedicate some articles (like this one) to explain that very jargon, or at least make it a bit less unfamiliar to you.&lt;/p&gt;




&lt;p&gt;Linux is a multi-user system, and it does not mean what you think it does (or at least what I did).&lt;/p&gt;

&lt;p&gt;A multi-user system is not just a system that allows having multiple users, but one that can also be used by many users at the same time. The keyword here is &lt;strong&gt;at the same time&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You might ask yourself, how can a computer be used at the same time by different people? Well, a computer does not require you to sit in front of it to use it. You can remotely access it for example using the program &lt;em&gt;Remote Desktop Connection&lt;/em&gt; if you're using Windows. Or using SSH to access the system via the command line. That way, multiple users can work on the same machine, using the same resources.&lt;/p&gt;

&lt;p&gt;Try to picture that scenario of multiple user accessing a computer, it's a mess. What's stopping user B from playing around with user A's work? As a person that likes to troll, I would say, nothing. The options are endless, and it stops being fun when you're user A.&lt;/p&gt;

&lt;p&gt;It seems that this trolling concern existed in the 70's too. Unix was built with the design of a multi-user architecture; it introduced file ownership and permissions. And Linux naturally inherited this design as well.&lt;/p&gt;

&lt;h2&gt;
  
  
  Unix multi-user system design
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Ownership
&lt;/h3&gt;

&lt;p&gt;Every file in the system belongs to a user and to a group. This is called ownership, and it enables the system to make the distinction between these 3 cases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A user that owns the file.&lt;/li&gt;
&lt;li&gt;A user that belongs to the group that owns the file.&lt;/li&gt;
&lt;li&gt;A user that is neither of the above. Which is called &lt;em&gt;other&lt;/em&gt; or &lt;em&gt;world&lt;/em&gt; as I've explained in the last article.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Permissions
&lt;/h3&gt;

&lt;p&gt;Permissions are &lt;em&gt;who gets to do what&lt;/em&gt; with a file. The who part is determined by ownership, it is one of the 3 cases I mentioned above.&lt;/p&gt;

&lt;p&gt;Now to the fun part, &lt;em&gt;do what&lt;/em&gt;. What can be done to a file? The answer is found in the first column in the output of &lt;code&gt;ls -l&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Read.&lt;/li&gt;
&lt;li&gt;Write.&lt;/li&gt;
&lt;li&gt;Execute.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These 3 permissions hold different meanings for files and directories. It's one of the things that I found troubling to understand when I was first learning Linux.&lt;/p&gt;

&lt;h4&gt;
  
  
  Permissions of a file
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Read: the file's content can be read. By using &lt;code&gt;cat&lt;/code&gt; or opening it with a text editor for example.&lt;/li&gt;
&lt;li&gt;Write: the file's content can be changed.&lt;/li&gt;
&lt;li&gt;Execute: the file can be considered a program and executed. If you ever downloaded an &lt;a href="https://appimage.org" rel="noopener noreferrer"&gt;AppImage&lt;/a&gt; before, you're likely to have encountered the error &lt;code&gt;Permission denied&lt;/code&gt;. The reason was because the file did not have the execute permission.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Permissions of a directory
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Read: the directory's content can be read, you can &lt;code&gt;ls&lt;/code&gt; the directory, but you cannot open it graphically by double clicking, I'll explain that in a bit.&lt;/li&gt;
&lt;li&gt;Write: the directory's content can be changed, meaning you can create/delete/rename/move files and directories within it.&lt;/li&gt;
&lt;li&gt;Execute: you can enter the directory, meaning &lt;code&gt;cd&lt;/code&gt; into it. This permission alone is not enough to open the directory graphically too.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So what's up with directories graphically? Well, nothing. Just think about it for a second.&lt;/p&gt;

&lt;p&gt;What happens exactly when you double click on a directory? Sounds like a stupid question right? I'll let you be the judge of that.&lt;/p&gt;

&lt;p&gt;A window pops up, &lt;strong&gt;showing&lt;/strong&gt; the content of that directory. But another thing happens as well, we &lt;strong&gt;enter&lt;/strong&gt; that directory.&lt;/p&gt;

&lt;p&gt;Ultimately, opening a directory graphically makes use of two permissions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Read permission: because the window lists the content of the directory.&lt;/li&gt;
&lt;li&gt;Execute permission: because we entering the directory.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Don't take my word for it though, I might be saying nonsense after all. Open your terminal, and play around with files/directories with different permissions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Chmoding playground
&lt;/h2&gt;

&lt;p&gt;What better way is there to understand than seeing what you're learning in action, right?&lt;/p&gt;

&lt;p&gt;In order to see the effect of the different permissions, you'll need to be able to change them. That's where the &lt;code&gt;chmod&lt;/code&gt; command comes into the picture. I'll briefly introduce it, refer to &lt;code&gt;man&lt;/code&gt; for more details.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;chmod&lt;/code&gt; command supports two syntaxes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Octal (I won't cover what octal is, or why the syntax was named after it)&lt;/li&gt;
&lt;li&gt;Symbolic&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Remember how a user can be either an owning user, a user that belongs to the owning group or neither? Well each of those gets a permission.&lt;/p&gt;

&lt;h3&gt;
  
  
  Octal
&lt;/h3&gt;

&lt;p&gt;The syntax is straightforward:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;chmod &amp;lt;XXX&amp;gt; file&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Where XXX is a 3 digit number. Reading from left to write:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1st digit: permission for the owning user.&lt;/li&gt;
&lt;li&gt;2nd digit: permission for the owning group&lt;/li&gt;
&lt;li&gt;3rd digit: permission for others (also called world, anyone that is neither of the above).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each permission is "represented" by a number:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Read: 4&lt;/li&gt;
&lt;li&gt;Write: 2&lt;/li&gt;
&lt;li&gt;Execute: 1&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To describe a permission as a digit, add the numbers of the permissions you wish to include. For example, the permission of a file that is readable and writable would be described with the number 6. Which is 4 (read permission) + 2 (write permission).&lt;/p&gt;

&lt;p&gt;Repeat the same process for the each digit to represent the file's permission for every kind of user.&lt;/p&gt;

&lt;p&gt;Say you want your file to be readable and writable for you (the owner), and only readable for anyone else:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;chmod 600 someFile.txt&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The first digit representing your permission. The second and third digits representing respectively the owner group and others' permissions, which is 0, none.&lt;/p&gt;

&lt;p&gt;You change your mind, you open your heart and want to share the file with others, but without having to worry about trolls (like myself). Instead of giving no permission to the group owner and others', you give them read access instead.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;chmod 644 someFile.txt&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You get the idea.&lt;/p&gt;

&lt;h3&gt;
  
  
  Symbolic
&lt;/h3&gt;

&lt;p&gt;This one is a bit tricky. You use these symbols to represent permissions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;u&lt;/code&gt; meaning user owner.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;g&lt;/code&gt; meaning group owner.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;o&lt;/code&gt; meaning others.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;r&lt;/code&gt; for read permission.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;w&lt;/code&gt; for write permission.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;x&lt;/code&gt; for execute permission.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's start simple.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;chmod +x someFile.txt&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This adds the execute permission for everyone. The user owner, the group owner, and others.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;chmod -x someFile.txt&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Removes the execute permission for everyone.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;chmod +rw someFile.txt&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Adds the read and write permissions for everyone. So far so good, I hope.&lt;/p&gt;

&lt;p&gt;Now it gets, compositional let's say.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;chmod u=rwx someFile.txt&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Assigns read, write and execute permissions to the user owner.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;chmod go=r someFile.txt&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Assigns the read permission to the group owner as well as to others.&lt;/p&gt;

&lt;p&gt;Etc.&lt;/p&gt;




&lt;p&gt;I hope you learned something :)&lt;/p&gt;

&lt;p&gt;Keep the trolls away.&lt;/p&gt;

&lt;p&gt;Photo by &lt;a href="https://unsplash.com/@jrkorpa?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Jr Korpa&lt;/a&gt; on &lt;a href="https://unsplash.com/photos/E2i7Hftb_rI?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

</description>
      <category>linux</category>
      <category>beginners</category>
      <category>terminal</category>
    </item>
    <item>
      <title>Helping Older Browsers Understand HTML5</title>
      <dc:creator>Mohamed Yamani</dc:creator>
      <pubDate>Tue, 19 Sep 2023 20:52:36 +0000</pubDate>
      <link>https://dev.to/yamanidev/helping-older-browsers-understand-html5-440d</link>
      <guid>https://dev.to/yamanidev/helping-older-browsers-understand-html5-440d</guid>
      <description>&lt;h2&gt;
  
  
  Table of content
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;Ancient browsers that do not support HTML5&lt;/li&gt;
&lt;li&gt;How do these browsers interpret HTML5 semantic elements?&lt;/li&gt;
&lt;li&gt;Okay, so what's the solution?&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;When HTML5 was released it brought semantic HTML elements to the table which in turn frequently replace the famous &lt;em&gt;divs&lt;/em&gt; and &lt;em&gt;spans&lt;/em&gt; that are notoriously used everywhere.&lt;/p&gt;

&lt;p&gt;The use of these semantic elements is very important, some of the reasons behind that being:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Offering people with disabilities a better navigation experience by creating a clear hierarchy of the content of the page for screen readers to parse.&lt;/li&gt;
&lt;li&gt;Helps your website's SEO ranking (Search Engine Optimization) by facilitating the indexing of the website by search engines.&lt;/li&gt;
&lt;li&gt;HTML elements now give a descriptive meaning to their content. An &lt;em&gt;aside&lt;/em&gt; is a lot more descriptive than the general-everywhere-use of &lt;em&gt;div&lt;/em&gt; or &lt;em&gt;span&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Ancient browsers that do not support HTML5
&lt;/h2&gt;

&lt;p&gt;Unfortunately though, not all browsers support HTML5 features (fully and/or partially) and that complicates things.&lt;/p&gt;

&lt;p&gt;We can't write our HTML twice; one that is semantic for browsers that are compatible and one for the older versions that are not. Because that is resource consuming in terms of authoring and maintenance.&lt;/p&gt;

&lt;p&gt;And we obviously cannot neglect the ones that do use ancient browsers (yes, some people do, surprisingly) because that could potentially mean decrease in revenue and visibility since a portion of people won't be able access our website properly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Now these cursed browsers are (partial to no compatibility for semantic HTML):
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Mozilla Firefox version 2 to 20&lt;/li&gt;
&lt;li&gt;Google Chrome version 4 to 25&lt;/li&gt;
&lt;li&gt;Safari version 3.1 to 6&lt;/li&gt;
&lt;li&gt;Internet Explorer version 6 to 9&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How do these browsers interpret HTML5 semantic elements?
&lt;/h2&gt;

&lt;p&gt;That's a good question, it's an edge case that needs to be treated.&lt;/p&gt;

&lt;p&gt;Naturally, incompatible browsers with HTML5 features won't recognize the new semantic elements like &lt;em&gt;nav&lt;/em&gt;, &lt;em&gt;header&lt;/em&gt;, &lt;em&gt;footer&lt;/em&gt; etc.&lt;/p&gt;

&lt;p&gt;So how do they parse them?&lt;/p&gt;

&lt;p&gt;Browsers treat them as &lt;em&gt;inline&lt;/em&gt; elements. Meaning they would go with the flow of text, they do not start a new line (the same default behavior of &lt;em&gt;img&lt;/em&gt; and &lt;em&gt;span&lt;/em&gt; for example).&lt;/p&gt;

&lt;h2&gt;
  
  
  Okay, so what's the solution?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;### The "meh" approach&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Some of the older browser versions allow CSS rules to be associated with semantic elements (for example IE9 was the first of IE to adopt this), we will be using that to our advantage.&lt;/p&gt;

&lt;p&gt;All you have to do is select the semantic elements and change their &lt;em&gt;display&lt;/em&gt; (from inline as we said) to &lt;em&gt;block&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;An example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;header&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="nt"&gt;section&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="nt"&gt;footer&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="nt"&gt;aside&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="nt"&gt;nav&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="nt"&gt;article&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="nt"&gt;figure&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;block&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is not the optimal solution nor the recommended one, it's meh.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;### The recommended approach&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We get JavaScript involved in the play by fundamentally creating the elements from scratch as such:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;nav&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;header&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;article&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// etc&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By the way, this code must be appended in the &lt;em&gt;head&lt;/em&gt; element either by linking to an external script or by writing the code inline using &lt;em&gt;script&lt;/em&gt; tag.&lt;/p&gt;

&lt;p&gt;The problem with this though is there's more than 100 semantic HTML element in the spec. And this code seems pretty lacking and is not reliable on real world projects.&lt;/p&gt;

&lt;p&gt;The best way to deal with this is by using &lt;em&gt;html5shiv&lt;/em&gt; (there's actually a funny story behind the debate whether it should be called shiv or shim).&lt;/p&gt;

&lt;p&gt;The script is in this &lt;a href="https://github.com/aFarkas/html5shiv" rel="noopener noreferrer"&gt;repo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;There are two ways to get the script (you can check them out in README of the repository), either by using &lt;em&gt;Bower&lt;/em&gt; or manually installing it.&lt;/p&gt;

&lt;p&gt;I prefer the manual installation via this &lt;a href="https://github.com/aFarkas/html5shiv/archive/master.zip" rel="noopener noreferrer"&gt;link&lt;/a&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;After extracting the ZIP file, copy either files &lt;em&gt;dist/html5shiv.js&lt;/em&gt; or &lt;em&gt;dist/html5shiv-printshiv.js&lt;/em&gt; to your project's directory.&lt;/li&gt;
&lt;li&gt;Include the copied script in the &lt;em&gt;head&lt;/em&gt; element&lt;/li&gt;
&lt;li&gt;Add this comment in the &lt;em&gt;head&lt;/em&gt; element after all the stylesheets:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!--[if lt IE 9]&amp;gt;
  &amp;lt;script src="bower_components/html5shiv/dist/html5shiv.js"&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;![endif]--&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Problem solved. You can now safely forget about the older browsers!&lt;/p&gt;

&lt;h2&gt;
  
  
  Thank you for reading!
&lt;/h2&gt;

&lt;p&gt;I hope you learned something new and enjoyed reading!&lt;/p&gt;

&lt;p&gt;Follow my blog and my &lt;a href="https://twitter.com/yamanidev" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; for more!&lt;/p&gt;

&lt;p&gt;Have a nice one.&lt;/p&gt;

&lt;p&gt;Photo by &lt;a href="https://unsplash.com/@lazycreekimages?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Michael Dziedzic&lt;/a&gt; on &lt;a href="https://unsplash.com/photos/gEN5Btvf2Eg?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

</description>
      <category>html</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
    <item>
      <title>Linux Fundamentals: Explaining the ls command and beyond</title>
      <dc:creator>Mohamed Yamani</dc:creator>
      <pubDate>Fri, 15 Sep 2023 08:46:43 +0000</pubDate>
      <link>https://dev.to/yamanidev/linux-fundamentals-explaining-the-ls-command-and-beyond-4o7n</link>
      <guid>https://dev.to/yamanidev/linux-fundamentals-explaining-the-ls-command-and-beyond-4o7n</guid>
      <description>&lt;p&gt;Originally published at &lt;a href="https://mohamedyamani.com/blog/linux-fundamentals-explaining-the-ls-command-and-beyond/" rel="noopener noreferrer"&gt;https://mohamedyamani.com&lt;/a&gt; on September 10, 2023.&lt;/p&gt;

&lt;p&gt;If you ever used a Linux system before, chances are you're familiar with the &lt;code&gt;ls&lt;/code&gt; command, or at least you know of it. Through understanding the output of this command, you can learn some fundamental concepts in Linux (or operating systems in general) like user management and file permissions. It's kinda fun, I promise.&lt;/p&gt;

&lt;p&gt;For those of you that are not familiar with the &lt;code&gt;ls&lt;/code&gt; command, I hope you can pick up at least this from the article...&lt;/p&gt;

&lt;h2&gt;
  
  
  Golden nugget
&lt;/h2&gt;

&lt;p&gt;If you ever find yourself unsure of what a command does, what argument does what, or the syntax of the command, always refer to the system's manual via the &lt;code&gt;man&lt;/code&gt; command. You don't know what &lt;code&gt;ls&lt;/code&gt; is? Screw Google. Enter &lt;code&gt;man ls&lt;/code&gt; in your terminal. Not sure why someone would call a command that outputs text a &lt;code&gt;cat&lt;/code&gt;? &lt;code&gt;man cat&lt;/code&gt; (stands for concatenate).&lt;/p&gt;

&lt;p&gt;Funnily enough, when I was first learning about this, I tried &lt;code&gt;man man&lt;/code&gt; right off the bat. Boy was it lovely to see that it worked and indeed returned the manual description of the manual. Don't take my word for it though, try it yourself!&lt;/p&gt;




&lt;p&gt;If you feel like sticking around a little bit more, I will try to explain the command for you.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: you will encounter the word "directory" in this article, it's a fancier name for "folder" used in Unix/Unix-like contexts.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Level 0
&lt;/h2&gt;

&lt;p&gt;The command &lt;code&gt;ls&lt;/code&gt; lists the content of a directory, content like files and other directories. It is the equivalent to the graphical way of double clicking on a folder and seeing the icons of the different folders and files. &lt;/p&gt;

&lt;p&gt;So how come &lt;code&gt;ls&lt;/code&gt; works even though we didn't provide a directory to list the content of? Well if you read the manual &lt;code&gt;man ls&lt;/code&gt; you would know! Develop that reflex my friend, you will need it.&lt;/p&gt;

&lt;p&gt;Entering &lt;code&gt;ls&lt;/code&gt; without providing a directory will list the content of the current directory by default. What current directory you say?&lt;/p&gt;

&lt;p&gt;Well the terminal is always pointing to a directory. By default when you open the terminal, it would be pointing at what's called the home directory, it is usually given the symbol &lt;code&gt;~&lt;/code&gt; in the prompt which is just a shorthand of &lt;code&gt;/home/&amp;lt;your-username&amp;gt;/&lt;/code&gt;. Don't take my word for it though, open up your terminal and enter &lt;code&gt;pwd&lt;/code&gt; to check the current directory (use &lt;code&gt;man&lt;/code&gt; to learn more about that command!).&lt;/p&gt;

&lt;h2&gt;
  
  
  Level 1
&lt;/h2&gt;

&lt;p&gt;Great. Now you can use the terminal to check the content of a directory. But now you're getting greedy, you want to extract more information -as you should-. Feel free to explore the arguments you can find in the manual! Some of the most common used ones would be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;ls -a&lt;/code&gt; to view hidden items. Notice how the new items all have names starting with a &lt;code&gt;.&lt;/code&gt;? That is how files are hidden in Linux/Unix. Neat right?&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ls -l&lt;/code&gt; to show more details about the listed items.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The last argument shows some cryptic output. That's our key to understanding more concepts!&lt;/p&gt;

&lt;h2&gt;
  
  
  Level 2
&lt;/h2&gt;

&lt;p&gt;The output of &lt;code&gt;ls -l&lt;/code&gt; would look something like this. Let's try to depict it.&lt;/p&gt;

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

&lt;p&gt;You can notice that each item is on a separate line. Each line provides a piece of information about the item in a column, sort of like a table.&lt;/p&gt;

&lt;h3&gt;
  
  
  Column 1: File type and permissions
&lt;/h3&gt;

&lt;p&gt;The first character denotes the file type:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;d&lt;/code&gt; for directory.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-&lt;/code&gt; for a regular file.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;i&lt;/code&gt; for a symbolic link (will not be covered in this article).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Notice how I said file type? Including directories? That's because in Linux, everything is a file. A directory is just a special kind of file. I might write an article about that someday! :)&lt;/p&gt;

&lt;p&gt;The remaining part of the column indicates the file's permissions. It is divided into 3 parts. The left most part is the user owner's permission, the middle one is the group's permission and the right most part represents the world's (others') permission.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;r&lt;/code&gt; stands for read. It takes the first position.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;w&lt;/code&gt; stands for write. It takes the second position.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;x&lt;/code&gt; stands for execute. It takes the third permission.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-&lt;/code&gt; indicates no permission depending on the position. If it's in the first one, it means the file does not have read permission. If it's in the second, it means no write permission, and so on.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I will assume that the notion of a user is familiar. However a &lt;em&gt;group&lt;/em&gt; might be a new term.&lt;/p&gt;

&lt;p&gt;A group is simply a collection of users. The introduction of such feature facilitates the administration of things like having the same permissions for a bunch of users.&lt;/p&gt;

&lt;p&gt;Finally, &lt;em&gt;others&lt;/em&gt;, or as some call it &lt;em&gt;world&lt;/em&gt;, is anyone that is not the user owner or the group owner.&lt;/p&gt;

&lt;p&gt;Notice also how many terms are being thrown here? And we're just getting started! That's what I meant by &lt;code&gt;ls&lt;/code&gt; being a key to learning some fundamental concepts. Brace yourself!&lt;/p&gt;

&lt;h3&gt;
  
  
  Column 2: Hard links count
&lt;/h3&gt;

&lt;p&gt;Quite the confusing name right, it's in fact simple. A hard link is a copy of a file. The number indicates how many copies exist of that file in the file system.&lt;/p&gt;

&lt;h3&gt;
  
  
  Column 3: User owner
&lt;/h3&gt;

&lt;h3&gt;
  
  
  Column 4: Group owner
&lt;/h3&gt;

&lt;h3&gt;
  
  
  Column 5: File size
&lt;/h3&gt;

&lt;p&gt;In bytes. You can look up the manual on which argument to use to display the sizes in &lt;em&gt;human&lt;/em&gt; readable format. On that note, search online how to properly search for keywords in the terminal manual.&lt;/p&gt;

&lt;h3&gt;
  
  
  Column 6: Last modified date and time
&lt;/h3&gt;

&lt;p&gt;The timestamp of when the file was last modified.&lt;/p&gt;

&lt;h3&gt;
  
  
  Finally, column 7: the file name
&lt;/h3&gt;

&lt;h2&gt;
  
  
  Level 3
&lt;/h2&gt;

&lt;p&gt;You realize by now how much there's to know. You've asked yourself plenty of questions while reading the article. I sure did while writing it! But that's the beauty of it. Explore away your curiosity, discover what you can!&lt;/p&gt;




&lt;p&gt;A lot of what has been briefly explained here could be developed into separate articles. I am planning on doing that someday in the near future :)&lt;/p&gt;

&lt;p&gt;Hope you learned something!&lt;/p&gt;

&lt;p&gt;Photo by &lt;a href="https://unsplash.com/@diane_soko?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Diane Picchiottino&lt;/a&gt; on &lt;a href="https://unsplash.com/photos/Avy65GwRDUU?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>terminal</category>
      <category>unix</category>
      <category>beginners</category>
    </item>
    <item>
      <title>My First Experience in Google Hash Code</title>
      <dc:creator>Mohamed Yamani</dc:creator>
      <pubDate>Sun, 10 Sep 2023 11:55:05 +0000</pubDate>
      <link>https://dev.to/yamanidev/my-first-experience-in-google-hash-code-578f</link>
      <guid>https://dev.to/yamanidev/my-first-experience-in-google-hash-code-578f</guid>
      <description>&lt;p&gt;We all know how important practicing is for learning crafts and honing skills. You become a better chef by cooking more often, a great painter by drawing and a skilled programmer by writing more code.&lt;/p&gt;

&lt;p&gt;What software engineers do -put simply- is solving real world problems using technology. To be a better engineer is to get better at solving problems.&lt;/p&gt;

&lt;p&gt;One of the ways you can apply what you've learned is through participating in coding competitions (and there are a lot, annually).&lt;/p&gt;

&lt;p&gt;Google for example organizes many competitions every year like &lt;a href="https://codingcompetitions.withgoogle.com/kickstart" rel="noopener noreferrer"&gt;Kick Start&lt;/a&gt; which is in 8 days, &lt;a href="https://codingcompetitions.withgoogle.com/codejam" rel="noopener noreferrer"&gt;Code Jam&lt;/a&gt; that starts in 14 days, &lt;a href="https://summerofcode.withgoogle.com" rel="noopener noreferrer"&gt;Google Summer of Code&lt;/a&gt; during summer (applications open next month, keep updated) and finally &lt;a href="https://codingcompetitions.withgoogle.com/hashcode" rel="noopener noreferrer"&gt;Hash Code&lt;/a&gt;, I will be sharing with you my first experience with this last one.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is Google Hash Code?
&lt;/h3&gt;

&lt;p&gt;Google Hash Code is a programming competition between teams (2 to 4 people a team) from all across the globe (over 97 countries).&lt;/p&gt;

&lt;p&gt;You are given a problem to solve in 5 hours "modeled off a real Google engineering challenge" as Google says.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prizes
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;1st place: 4000$ USD&lt;/li&gt;
&lt;li&gt;2nd place: 2000$ USD&lt;/li&gt;
&lt;li&gt;3rd place: 1000$ USD&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Along with some Google products to the top rankings.&lt;/p&gt;

&lt;h3&gt;
  
  
  Who can join?
&lt;/h3&gt;

&lt;p&gt;You must be at least 16 years old to participate in the contest, and at least 18 years old to be eligible for the final round.&lt;/p&gt;

&lt;h3&gt;
  
  
  My story
&lt;/h3&gt;

&lt;p&gt;A friend of mine approached me a month before the registrations to participate with him and a friend of his in Hash Code, I had completely forgotten about it at that time, I got so excited and immediately accepted to roll on with them.&lt;/p&gt;

&lt;p&gt;Sadly enough, final exams were a week after Hash Code but I regret not giving preparation for the competition enough time nevertheless. The only thing we did to prepare was meeting up a week before the competition to practice past problems (they're easily found in Hash Code's website).&lt;/p&gt;

&lt;p&gt;As we tried to come up with solutions to last year's qualification round problem we got very overwhelmed by it, we knew it would be a challenge obviously, but did not expect anything near this difficulty. Still after 4 hours of brainstorming and discussing possible approaches, we did not move an inch and it was depressing, so we just called it a day and went back to studying for school.&lt;/p&gt;

&lt;p&gt;Fast forward to the competition day (a week later), it started on 6:30 PM (if I remember correctly) here in Algeria. We met up at my room, installed our setups and prepared everything needed to kickstart and waited for the problem statement excitedly.&lt;/p&gt;

&lt;p&gt;We downloaded the PDF and started reading through the 10 pages (it was even longer than last year's which were 5) and it took as around 35 minutes to "absorb" it. Each one of us started thinking through some possible solutions and how to implement them for an hour-ish long. What was weird and funny though is that we all found ourselves forgetting the problem statement mid-way and that costed us a lot of time perhaps due to the many variables, circumstances and conditions to take into account but surely for our lack of practice.&lt;/p&gt;

&lt;p&gt;We discovered that one of the test cases given through an example is one of the problems' inputs, so we copied the results of the example's output and submitted it, 1002 points received for that. But guess what, time was already up haha, the scoreboard was frozen, so our score was 0.&lt;/p&gt;

&lt;p&gt;So basically, we yet again did nothing, not even a single implementation of the ideas we had.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So why am I telling you this?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I shared my experience with you to emphasize that you do not have to be good at something to try it out, everyone starts somewhere.&lt;/p&gt;

&lt;p&gt;If you stumble upon any programming competition, join it immediately without any second thought, figure things along the way and enjoy yourself!&lt;/p&gt;

&lt;p&gt;Don't question whether you know the technology X or have the skill Y, join to learn from the experience and have fun!&lt;/p&gt;

&lt;p&gt;One thing I sure took away with me is feeling extremely stupid, and I am happy with that feeling because it is humbling, it is a good reminder that there is still a long way to go.&lt;/p&gt;

&lt;p&gt;That is what I love most about this field especially, learning never ends, it is part of the journey. You will always remain a student!&lt;/p&gt;

&lt;h3&gt;
  
  
  Takeaway
&lt;/h3&gt;

&lt;p&gt;Don't feel intimidated by competitions.&lt;/p&gt;

&lt;p&gt;The worst thing that could happen is to get a score of 0 (like yours truly did), learn about this type of competitions, and come better prepared next time (like I sure will)!&lt;br&gt;
Now that doesn't sound so bad after all now does it?&lt;/p&gt;

&lt;p&gt;Don't ask yourself too many questions about it. Just join!&lt;/p&gt;

&lt;p&gt;You have too much to lose if you don't.&lt;/p&gt;

&lt;p&gt;You most probably will meet new people, get exposed to different technologies, learn a thing or two and on top of that, have fun!&lt;/p&gt;

&lt;h2&gt;
  
  
  Thank you for reading!
&lt;/h2&gt;

&lt;p&gt;That was it ladies and gentlemen, I hope you enjoyed the article!&lt;/p&gt;

&lt;p&gt;Any feedback or constructive critique is warmly welcomed and appreciated, so please tell me what you think in the comments so I can better the quality. Thanks for reading ❤️!&lt;/p&gt;

&lt;p&gt;Follow my blog and my &lt;a href="https://twitter.com/yamanidev" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; for more!&lt;/p&gt;

&lt;p&gt;Have a nice one!&lt;/p&gt;

&lt;p&gt;Photo by &lt;a href="https://unsplash.com/@mitchel3uo?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Mitchell Luo&lt;/a&gt; on &lt;a href="https://unsplash.com/photos/jz4ca36oJ_M?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

</description>
      <category>google</category>
      <category>competition</category>
      <category>algorithms</category>
      <category>datastructures</category>
    </item>
    <item>
      <title>How ChatGPT Can Hurt Your Problem Solving Skills: An Anecdote</title>
      <dc:creator>Mohamed Yamani</dc:creator>
      <pubDate>Fri, 08 Sep 2023 08:46:10 +0000</pubDate>
      <link>https://dev.to/yamanidev/how-chatgpt-can-hurt-your-problem-solving-skills-an-anecdote-359i</link>
      <guid>https://dev.to/yamanidev/how-chatgpt-can-hurt-your-problem-solving-skills-an-anecdote-359i</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;ChatGPT is one of those tools that are -without exaggeration- revolutionary. With its release, the world enters a completely different phase, which is only natural. With a tool that relieves you of the tedious searching you had to do and digging around the internet for answers, you get your results by prompting it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Discovery
&lt;/h2&gt;

&lt;p&gt;When it was released, everyone was using it. I started noticing people from my circle ChatGPT'ing their way through everything. From solving math equations, summarizing documents to writing cover letters and presentations. It was wild.&lt;/p&gt;

&lt;p&gt;I couldn't blame them, I saw how practical it was, how much time you could save by using it, which is really what tools are for. However, I am personally very slow when it comes to adopting hyped up tools, even when it's as grand as ChatGPT. It would require you to subscribe to releases of shiny new things, which I find distracting as there are new tools getting published very frequently.&lt;/p&gt;

&lt;p&gt;Last July, I had my finals. And as per usual, you have to go through ~200 slides of materials per class (we had 8, so that's 1600 slides). After the course of some months, and after seeing how effective ChatGPT has been for my friends and classmates (and occasionally myself as well), I had decided to use it to prepare for exams, since -naturally- I am always behind when it comes to studies. Since I am someone that's somewhat articulate and precise when it comes to learning, most of my prompts where of the sort:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;What's the difference between UART and SPI in embedded systems?&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;What's the difference between security and liveliness in distributed systems?&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;What's the difference between a service and a thread in android?&lt;/em&gt;
etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Getting hooked
&lt;/h2&gt;

&lt;p&gt;Little by little, I started developing the reflexes to prompt ChatGPT for answers instead of using DuckDuckGo. I started noticing that I am visiting websites like Stack Overflow and GitHub less and less for answers and code snippets, and sticking with ChatGPT for everything. Only to notice 2 weeks ago what my reliance has lead to.&lt;/p&gt;

&lt;p&gt;The amount of time I spent thinking of solutions decreased, I would almost always just prompt for the code and paste it with some adjustments. I noticed that my problem solving became troubled and slow, that it has deteriorated. &lt;/p&gt;

&lt;h2&gt;
  
  
  Trying to get unhooked
&lt;/h2&gt;

&lt;p&gt;I started to consciously fight the urge/reflex to prompt for answers, and try to come up with ones of my own in the traditional way I used to. Thankfully, I am slowly getting back to normal.&lt;/p&gt;

&lt;p&gt;The solution here lies not in one of the extremes, either relying almost completely on the tool, or refraining from it, rather it is somewhere in the middle. To find a balance in which you could benefit from the tool without relying too much on it to the point of damage.&lt;/p&gt;

&lt;p&gt;I personally found the middle ground is to limit my prompts to a set of questions/scenarios:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Scaffolding projects or libraries.&lt;/li&gt;
&lt;li&gt;Comparative questions, especially when it comes to figuring out which tool to pick for which job.&lt;/li&gt;
&lt;li&gt;Learning new concepts.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;The key takeaway I would say from this anecdote is, to pay attention to how we're using our everyday tools, how much we're relying on them, whether that's a good or a bad thing. Because tools affect us, and as ironic as it sounds, we could very well end up being enslaved by our creation.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: Funnily enough, I prompted for a title and a description for this post (they suck, I am going with my own). Guess I have some more work to do...&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://mohamedyamani.com/blog/how-chatgpt-can-hurt-your-problem-solving-skills-anecdote/" rel="noopener noreferrer"&gt;https://mohamedyamani.com&lt;/a&gt; on September 3, 2023.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>chatgpt</category>
      <category>programming</category>
      <category>softwaredevelopment</category>
      <category>coding</category>
    </item>
    <item>
      <title>The Migration Adventure: CRA to Vite and npm to pnpm</title>
      <dc:creator>Mohamed Yamani</dc:creator>
      <pubDate>Sun, 27 Aug 2023 10:24:46 +0000</pubDate>
      <link>https://dev.to/yamanidev/the-migration-adventure-cra-to-vite-and-npm-to-pnpm-37fi</link>
      <guid>https://dev.to/yamanidev/the-migration-adventure-cra-to-vite-and-npm-to-pnpm-37fi</guid>
      <description>&lt;p&gt;As I was migrating a client's project from CRA to Vite I encountered plenty of issues. Some of which were due to certain imports that are specific to Webpack, the other ones were due to me using &lt;code&gt;pnpm&lt;/code&gt; as opposed to &lt;code&gt;npm&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That wasn't a smart move, migrating to another build tool as well as another package manager at once. So I switched back to using &lt;code&gt;npm&lt;/code&gt; to finish my Vite migration, fixed the errors, all good.&lt;/p&gt;

&lt;p&gt;When I tried using &lt;code&gt;pnpm&lt;/code&gt; again and installed the packages using it, it kept throwing many errors that package X, Y, Z are not installed, which is weird, because the &lt;code&gt;npm&lt;/code&gt; version works just fine!&lt;/p&gt;

&lt;p&gt;Via &lt;code&gt;pnpm import&lt;/code&gt;, the existing lock files are parsed and &lt;code&gt;pnpm-lock.yaml&lt;/code&gt; gets generated, so the lock files should have the same content.&lt;/p&gt;

&lt;p&gt;It is true that all the dependencies that are mentioned in the lock files will be installed by &lt;code&gt;pnpm&lt;/code&gt; without fault. However, due to how &lt;code&gt;npm&lt;/code&gt; installs packages and their dependencies, you will find yourself being able to use a dependency of a package without explicitly installing.&lt;/p&gt;

&lt;p&gt;That's exactly what happened, notably with &lt;code&gt;date-fns&lt;/code&gt; and some other packages. How &lt;code&gt;npm&lt;/code&gt; structures your &lt;code&gt;node_modules/&lt;/code&gt; allows you to import &lt;code&gt;date-fns&lt;/code&gt; even if it wasn't present as a dependency in your &lt;code&gt;package.json&lt;/code&gt;, as long as some other package depends on it.&lt;/p&gt;

&lt;p&gt;Bottom line, explicit is better than implicit.&lt;/p&gt;

&lt;p&gt;I downloaded the missing packages like a good boy and life moved on 🙂.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;p&gt;I followed &lt;a href="https://www.robinwieruch.de/vite-create-react-app/" rel="noopener noreferrer"&gt;this article&lt;/a&gt; to switch from CRA to Vite, it was very helpful.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>npm</category>
      <category>pnpm</category>
      <category>vite</category>
    </item>
    <item>
      <title>Basic Introduction to the Internet and the Web</title>
      <dc:creator>Mohamed Yamani</dc:creator>
      <pubDate>Sun, 14 Nov 2021 06:38:06 +0000</pubDate>
      <link>https://dev.to/yamanidev/basic-introduction-to-the-internet-and-the-web-nf0</link>
      <guid>https://dev.to/yamanidev/basic-introduction-to-the-internet-and-the-web-nf0</guid>
      <description>&lt;h2&gt;
  
  
  Table of content
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;What is the internet?&lt;/li&gt;
&lt;li&gt;How are computers linked via the internet?&lt;/li&gt;
&lt;li&gt;The journey of data sent between two devices&lt;/li&gt;
&lt;li&gt;How do we surf the web?&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Similarly to electricity, we use the internet on a daily basis without knowing how any of them function behind the scenes.&lt;/p&gt;

&lt;p&gt;As a web developer, having a basic understanding of the internet and its different parts gives you more perspective on the environment you're working on, which broadens your knowledge in this field.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is the internet?
&lt;/h2&gt;

&lt;p&gt;The internet is a network of networks.&lt;/p&gt;

&lt;p&gt;Great, very informative, the hell is a network?&lt;/p&gt;

&lt;p&gt;A network is a number of connected devices (computers, phones, or even a smart refrigerator) through Wi-Fi, Bluetooth or cables.&lt;/p&gt;

&lt;h2&gt;
  
  
  How are computers linked via the internet?
&lt;/h2&gt;

&lt;p&gt;Since the internet is this vast network; a large number of connected devices…&lt;/p&gt;

&lt;p&gt;What kind of connection ensures that every single device is connected to every other device in this network?&lt;/p&gt;

&lt;p&gt;The answer is, cables!&lt;/p&gt;

&lt;p&gt;Yep, long copper or optical fibers under the seas.&lt;/p&gt;

&lt;p&gt;Take a look at this &lt;a href="https://www.submarinecablemap.com" rel="noopener noreferrer"&gt;map&lt;/a&gt; that covers all the fibers in the world! Pretty cool.&lt;/p&gt;

&lt;p&gt;These cables get taken care of by your country's telephone infrastructure, and get integrated with the phone-line that reaches every house.&lt;/p&gt;

&lt;p&gt;Simply put, internet arrives to your doorstep via the phone-line.&lt;/p&gt;

&lt;p&gt;Phone-lines transmit light signals, in order to use the internet, these light signals must be converted to electricity via a &lt;strong&gt;modem&lt;/strong&gt;, which you connect to via Wi-Fi or Ethernet.&lt;/p&gt;

&lt;h2&gt;
  
  
  The journey of data sent between two devices
&lt;/h2&gt;

&lt;p&gt;In order to send data from a device to another, a connection must first be established.&lt;/p&gt;

&lt;p&gt;What ensures successful transmission (which means data sent to the right receiver) are pieces of equipment called &lt;strong&gt;routers&lt;/strong&gt;. Let's take an example:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Person A&lt;/strong&gt; wants to send a message to &lt;strong&gt;Person B&lt;/strong&gt; through the internet.&lt;/p&gt;

&lt;p&gt;Upon &lt;strong&gt;Person A&lt;/strong&gt; hitting &lt;em&gt;send&lt;/em&gt;, the message is transmitted via the phone-line to reach a router.&lt;/p&gt;

&lt;p&gt;The router receives the data and redirects it to the right receiver (or &lt;strong&gt;Person B&lt;/strong&gt; in this case). That's why they're called routers, they define the correct route data goes through.&lt;/p&gt;

&lt;p&gt;The router of this example is one of many special interconnected routers that are part of an &lt;strong&gt;ISP&lt;/strong&gt; (Short for: &lt;em&gt;Internet Service Provider&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;An &lt;strong&gt;ISP&lt;/strong&gt; is an organization that sells internet, web hosting etc. It takes care of distributing internet and its services.&lt;/p&gt;

&lt;h2&gt;
  
  
  How do we surf the web?
&lt;/h2&gt;

&lt;p&gt;We access the web using software called &lt;strong&gt;browsers&lt;/strong&gt; which allow us to view websites and navigate through them.&lt;/p&gt;

&lt;p&gt;More formally, a browser is a software that reads website documents (&lt;em&gt;HTML&lt;/em&gt; and &lt;em&gt;CSS&lt;/em&gt; files) and executes its linked scripts -&lt;em&gt;JavaScript&lt;/em&gt;-&lt;/p&gt;

&lt;p&gt;The way you navigate to websites is through the address bar, where you write a website's link (more formally, the &lt;strong&gt;&lt;em&gt;URL&lt;/em&gt;&lt;/strong&gt;):&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;URL example&lt;/strong&gt;: &lt;a href="http://www.facebook.com" rel="noopener noreferrer"&gt;http://www.facebook.com&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;http&lt;/strong&gt;: short for Hyper Text Transfer Protocol which is a set of rules for fetching resources (HTML, CSS, images etc.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;www&lt;/strong&gt;: the sub-domain&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;facebook&lt;/strong&gt;: the domain name&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;com&lt;/strong&gt;: the top-level-domain&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;Usually when we navigate to websites, we omit the &lt;strong&gt;&lt;em&gt;http&lt;/em&gt;&lt;/strong&gt; part of the &lt;strong&gt;&lt;em&gt;URL&lt;/em&gt;&lt;/strong&gt;, and it works just fine because the browser adds it by default when it is missing because it is an essential part of the &lt;strong&gt;&lt;em&gt;URL&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Now that our &lt;strong&gt;&lt;em&gt;URL&lt;/em&gt;&lt;/strong&gt; is typed and we press &lt;em&gt;Enter&lt;/em&gt;… is where the fun all begins!&lt;/p&gt;

&lt;p&gt;Continuing on the &lt;strong&gt;URL&lt;/strong&gt; example &lt;a href="http://www.facebook.com" rel="noopener noreferrer"&gt;www.facebook.com&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1. The browser checks the cache for the DNS record
&lt;/h3&gt;

&lt;p&gt;The browser checks in the cache memory for a previous entry of the domain name (facebook.com) in a &lt;strong&gt;DNS&lt;/strong&gt; record.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DNS&lt;/strong&gt; (short for Domain Name System) is a number of &lt;strong&gt;servers&lt;/strong&gt; that map each domain name to a corresponding numeric address called &lt;strong&gt;IP address&lt;/strong&gt; (short for &lt;em&gt;Internet Protocol&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;Just bear with me a little!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Servers&lt;/strong&gt; are powerful computers running applications that listen to &lt;strong&gt;&lt;em&gt;HTTP&lt;/em&gt;&lt;/strong&gt; requests from clients (usually browsers) and serve them with resources (or error codes when something goes wrong. For example a missing resource which returns the famous 404 error code).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;IP addresses&lt;/strong&gt; are unique numeric addresses given to each and every device connected to the internet.&lt;/p&gt;

&lt;p&gt;Writing out (and remembering) &lt;em&gt;&lt;a href="http://www.facebook.com" rel="noopener noreferrer"&gt;www.facebook.com&lt;/a&gt;&lt;/em&gt; is much more easier than 69.63.181.15 (Facebook's IP address). That is why we use &lt;strong&gt;DNS&lt;/strong&gt; which stores mappings of domain names to their corresponding IP addresses, exactly like a phone book.&lt;/p&gt;

&lt;p&gt;Regressing back to our explanation.&lt;/p&gt;

&lt;p&gt;If the browser finds the corresponding IP address of the domain name in cache memory, it sends an HTTP request to the mapped IP address of the domain name.&lt;/p&gt;

&lt;p&gt;If the domain name is not in cache, the ISP's DNS server runs a DNS query; searching different DNS servers on the internet to find the given domain name's IP address, jumping from DNS server to another until it finds it!&lt;/p&gt;

&lt;h3&gt;
  
  
  2. The browser sends an HTTP request to the website's server to fetch resources
&lt;/h3&gt;

&lt;p&gt;Upon finding the website's server IP address (thanks to DNS), the browser issues an HTTP request to the server to get the necessary documents of the website, from HTML and CSS files to the web page's images.&lt;/p&gt;

&lt;p&gt;The server issues a response and sends back the requested resources, if everything goes well (no errors).&lt;/p&gt;

&lt;p&gt;All these resources get rendered (read) by the browser and displayed!&lt;/p&gt;

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

&lt;p&gt;That was a brief introduction to functioning of the internet and the web. We barely scratched the surface, and made everything seem simple and cozy, it's not the case.&lt;/p&gt;

&lt;p&gt;The infrastructure underneath the internet is much more complex than that and is very interesting, we only covered some basics in this article, maybe we will dive into more complex concepts in the future!&lt;/p&gt;

&lt;h2&gt;
  
  
  Thank you for reading!
&lt;/h2&gt;

&lt;p&gt;That was it. I hope you learned something new and enjoyed reading!&lt;/p&gt;

&lt;p&gt;Any feedback or constructive critique is warmly welcomed and appreciated, so please tell me what you think in the comments so I can better the quality. Thanks for reading ❤️&lt;/p&gt;

&lt;p&gt;Follow my blog and my &lt;a href="https://twitter.com/yamanidev" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; for more!&lt;/p&gt;

&lt;p&gt;Have a nice one.&lt;/p&gt;

&lt;p&gt;Photo by &lt;a href="https://unsplash.com/@nasa?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;NASA&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/internet?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>web</category>
      <category>internet</category>
      <category>introduction</category>
    </item>
    <item>
      <title>Understanding The Box Model in CSS</title>
      <dc:creator>Mohamed Yamani</dc:creator>
      <pubDate>Sat, 06 Nov 2021 05:59:53 +0000</pubDate>
      <link>https://dev.to/yamanidev/understanding-the-box-model-in-css-1af</link>
      <guid>https://dev.to/yamanidev/understanding-the-box-model-in-css-1af</guid>
      <description>&lt;h2&gt;
  
  
  Table of content
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;What's the box model?&lt;/li&gt;
&lt;li&gt;Types of boxes&lt;/li&gt;
&lt;li&gt;Box sizing&lt;/li&gt;
&lt;li&gt;Bonus tip&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;When you're starting off with learning HTML and CSS, things can get overwhelming pretty quickly. At least they did for me. &lt;/p&gt;

&lt;p&gt;You find that there's a plethora of HTML elements and CSS properties and values, and you start thinking that you need to start memorizing them all. Or how else would you learn to build web pages, right?&lt;/p&gt;

&lt;p&gt;Wrong.&lt;/p&gt;

&lt;p&gt;Thanks to google, you can look up things when you need them. Details like how to disable the resizing of a &lt;code&gt;textarea&lt;/code&gt; element, or change the type of cursor on an element.&lt;/p&gt;

&lt;p&gt;But that does not apply across the board.&lt;/p&gt;

&lt;p&gt;There are some important concepts that you must understand very well in order to build a solid foundation to ease your progression and growth in web development.&lt;/p&gt;

&lt;p&gt;It is the understanding of these concepts that you should focus on doing. The cascading behavior of CSS, specificity, what browsers are, client/server architecture, all fall into this category.&lt;/p&gt;

&lt;p&gt;One of CSS foundational pillars is the box model. It is how every element renders in your browser.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's the box model?
&lt;/h2&gt;

&lt;p&gt;It's a CSS standard that represents the elements of a document as boxes with certain properties (sizing, positioning, stack of elements...) based on CSS styles.&lt;/p&gt;

&lt;p&gt;Put simply, every HTML element is a box of this sort:&lt;/p&gt;

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

&lt;p&gt;Every box has a &lt;strong&gt;content area&lt;/strong&gt;. An element's content could be text, an image, nested elements etc.&lt;/p&gt;

&lt;p&gt;In addition to the content area, an element may also have (as shown above):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Padding area&lt;/strong&gt;: space between the content and the border. The size of this area is defined by padding properties: &lt;code&gt;padding-top&lt;/code&gt;, &lt;code&gt;padding-right&lt;/code&gt;, &lt;code&gt;padding-bottom&lt;/code&gt; and &lt;code&gt;padding-left&lt;/code&gt;. Or simply the &lt;code&gt;padding&lt;/code&gt; shorthand.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Border are&lt;/strong&gt;: space between the padding and the margin. The size of this area is defined by the &lt;code&gt;border-width&lt;/code&gt; properties (same drill as the padding: top, right, bottom and left).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Margin area&lt;/strong&gt;: space between an element and its neighbors. The size of this area is defined by the &lt;code&gt;margin&lt;/code&gt; properties, negative values can be provided for margins.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Quick explanation of shorthands (feel free to skip if you are familiar with them):
&lt;/h3&gt;

&lt;p&gt;Shorthand properties are CSS properties that combine other properties. We use them to write less code and easily read it.&lt;/p&gt;

&lt;p&gt;We'll use &lt;code&gt;padding&lt;/code&gt; as an example, the same idea applies for other shorthands as well.&lt;/p&gt;

&lt;p&gt;The shorthand property &lt;code&gt;padding&lt;/code&gt; can take:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One value: &lt;code&gt;padding: 1rem&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the same as writing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;padding-right&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="nt"&gt;rem&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;padding-top&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="nt"&gt;rem&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;padding-bottom&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="nt"&gt;rem&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;padding-left&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="nt"&gt;rem&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Two values: &lt;code&gt;padding: 1rem 2rem&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Which is equivalent to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;padding-top&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="nt"&gt;rem&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;padding-bottom&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="nt"&gt;rem&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;padding-right&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;2&lt;/span&gt;&lt;span class="nt"&gt;rem&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;padding-left&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;2&lt;/span&gt;&lt;span class="nt"&gt;rem&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Four values: &lt;code&gt;padding: 1rem 2rem 3rem 4rem&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That element is going to look weird as hell but just ignore it, it's for the sake of example :3&lt;/p&gt;

&lt;p&gt;It's the same as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;padding-top&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="nt"&gt;rem&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;padding-right&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;2&lt;/span&gt;&lt;span class="nt"&gt;rem&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;padding-bottom&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;3&lt;/span&gt;&lt;span class="nt"&gt;rem&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;padding-left&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;4&lt;/span&gt;&lt;span class="nt"&gt;rem&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A rule of thumb to remember this last part is to picture the motion of a clock: it goes from the top, to the right, to the bottom and then to the left.&lt;/p&gt;

&lt;h2&gt;
  
  
  Types of boxes
&lt;/h2&gt;

&lt;p&gt;Now that we've had an overview of how elements are represented as boxes. We'll now discover how different types of boxes have different behaviors.&lt;/p&gt;

&lt;p&gt;The different types of boxes are based on the &lt;code&gt;display&lt;/code&gt; values: &lt;code&gt;block&lt;/code&gt;, &lt;code&gt;inline&lt;/code&gt; and &lt;code&gt;inline-block&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I highly suggest you mess around with this for a bit to get the hang of it. &lt;/p&gt;

&lt;h3&gt;
  
  
  Block type box
&lt;/h3&gt;

&lt;p&gt;Elements that fall into this type are those that have &lt;code&gt;display&lt;/code&gt; property set to &lt;code&gt;block&lt;/code&gt;, either by default (like &lt;code&gt;div&lt;/code&gt;) or manually (adding &lt;code&gt;display: block&lt;/code&gt; to the element with CSS).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Starts on a new line.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;height&lt;/code&gt;, &lt;code&gt;width&lt;/code&gt;, &lt;code&gt;margin&lt;/code&gt;, &lt;code&gt;padding&lt;/code&gt; are all applied and work as expected.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The element's width will fill its parent container unless otherwise specified.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Inline type box
&lt;/h3&gt;

&lt;p&gt;Elements that fall into this type are those that have &lt;code&gt;display&lt;/code&gt; property set to &lt;code&gt;inline&lt;/code&gt;, either by default (like &lt;code&gt;span&lt;/code&gt;) or manually (adding &lt;code&gt;display: inline&lt;/code&gt; to the element with CSS).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;If there's remaining space, it gets placed next to the previous element. Otherwise, it starts on a new line.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;height&lt;/code&gt; and &lt;code&gt;width&lt;/code&gt; properties have no effect on the element.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Horizontal &lt;code&gt;margin&lt;/code&gt; and &lt;code&gt;padding&lt;/code&gt; are applied and work as expected.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Vertical &lt;code&gt;margin&lt;/code&gt; and &lt;code&gt;padding&lt;/code&gt; are a bit tricky here, so bear with me. Both of the vertical properties are applied (you can check this using your developer tools), but they do not work as expected:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;margin&lt;/code&gt; does not have any effect. No spacing takes place between the inline element and adjacent elements.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;padding&lt;/code&gt; has an effect. You can test this out by adding a background color, it does not affect adjacent elements though. The padding does not push the other elements.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;It is very important to experiment with the above, this kind of details cannot be understood through reading only. Create block and inline elements and play around with their &lt;code&gt;width&lt;/code&gt;, &lt;code&gt;height&lt;/code&gt;, &lt;code&gt;margin&lt;/code&gt; and &lt;code&gt;padding&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Inline-block type box
&lt;/h3&gt;

&lt;p&gt;Yep, you read this right. This box right here is the offspring of the last two types.&lt;/p&gt;

&lt;p&gt;Elements that fall into this type are those that have &lt;code&gt;display&lt;/code&gt; property set to &lt;code&gt;inline-block&lt;/code&gt;, either by default (like &lt;code&gt;button&lt;/code&gt;) or manually (adding &lt;code&gt;display: inline-block&lt;/code&gt; to the element with CSS).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Behaves like inline: sits next to previous element if there's remaining space, or starts on a new line otherwise.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;width&lt;/code&gt;, &lt;code&gt;height&lt;/code&gt;, &lt;code&gt;margin&lt;/code&gt; and &lt;code&gt;padding&lt;/code&gt; behave as expected.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Box sizing
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;box-sizing&lt;/code&gt; is a CSS property that defines how the properties &lt;code&gt;height&lt;/code&gt;, &lt;code&gt;width&lt;/code&gt;, &lt;code&gt;border&lt;/code&gt; and &lt;code&gt;padding&lt;/code&gt; work together. &lt;/p&gt;

&lt;p&gt;It has 2 values (or modes):&lt;/p&gt;

&lt;p&gt;We'll have this code examined in both modes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;Banana man&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;300px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;200px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="no"&gt;red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;content-box&lt;/code&gt; (the default)
&lt;/h3&gt;

&lt;p&gt;The rendered dimensions would not be equal to the &lt;code&gt;height&lt;/code&gt; and &lt;code&gt;width&lt;/code&gt; specified in your CSS.&lt;/p&gt;

&lt;p&gt;But rather (for the width) &lt;code&gt;width&lt;/code&gt; + &lt;code&gt;padding-left&lt;/code&gt; + &lt;code&gt;padding-right&lt;/code&gt; + &lt;code&gt;border-left-width&lt;/code&gt; + &lt;code&gt;border-right-width&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Visual representation from my developer tools (I use Firefox, this is from Firefox. Use Firefox):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcfnaul99lq4phfd929ot.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcfnaul99lq4phfd929ot.png" alt="box model in developer tools of previous example" width="351" height="128"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can see that what &lt;code&gt;height&lt;/code&gt; and &lt;code&gt;width&lt;/code&gt; did is specify the content area dimensions, but not the overall element size.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;border-box&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;The rendered dimensions are exactly the values of &lt;code&gt;height&lt;/code&gt; and &lt;code&gt;width&lt;/code&gt; specified in your CSS.&lt;/p&gt;

&lt;p&gt;To enable this mode, we'll add &lt;code&gt;box-sizing: border-box&lt;/code&gt; to our &lt;code&gt;div&lt;/code&gt;. We get this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3p7pnf0ezcydz0s0a7gv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3p7pnf0ezcydz0s0a7gv.png" alt="box model in developer tools for border-box" width="351" height="127"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, the dimensions of the content area would be computed so that the overall size of our element matches 200px width and 300px height.&lt;/p&gt;

&lt;p&gt;This mode is often the most used and is included in CSS resets. This way, it is easy to match your website design pixel-perfectly, letting the browser enjoy computing the difference.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bonus tip (debugging CSS)
&lt;/h2&gt;

&lt;p&gt;Since everything in a website is a rectangular box, it would be easy to help ourselves visualize that in our websites.&lt;/p&gt;

&lt;p&gt;Whenever I encounter a bug, or a behavior I do not understand in my website (layout, positioning etc), I add &lt;code&gt;border: 1px solid red&lt;/code&gt; to all the elements I am skeptical about.&lt;/p&gt;

&lt;p&gt;I would change the color to differentiate between them though. You get the point.&lt;/p&gt;

&lt;p&gt;That way, you get a better picture of the layout of your website, how everything is positioned, the margins, the paddings etc. Without having to check every element individually using developer tools.&lt;/p&gt;

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

&lt;p&gt;TLDR; every website is a bunch of rectangular boxes nested inside other rectangular boxes. Boxes everywhere.&lt;/p&gt;

&lt;p&gt;So that was the box model for you. One of the key concepts of CSS. One topic down (hopefully :3), many to go!&lt;/p&gt;

&lt;h2&gt;
  
  
  Thank you for reading!
&lt;/h2&gt;

&lt;p&gt;That was it. I hope you learned something new and enjoyed reading!&lt;/p&gt;

&lt;p&gt;Any feedback or constructive critique is warmly welcomed and appreciated, so please tell me what you think in the comments so I can better the quality. Thanks for reading ❤️&lt;/p&gt;

&lt;p&gt;Follow my blog and my &lt;a href="https://twitter.com/yamanidev" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; for more!&lt;/p&gt;

&lt;p&gt;Have a nice one.&lt;/p&gt;

&lt;p&gt;Photo by &lt;a href="https://unsplash.com/@kelli_mcclintock?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Kelli McClintock&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/boxes?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

</description>
      <category>css</category>
      <category>beginners</category>
      <category>webdev</category>
      <category>html</category>
    </item>
  </channel>
</rss>
