<?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: Vasco Abelha</title>
    <description>The latest articles on DEV Community by Vasco Abelha (@vabelha).</description>
    <link>https://dev.to/vabelha</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%2F150293%2Ff56fcda2-cd48-47b3-86f2-e8f55586169c.png</url>
      <title>DEV Community: Vasco Abelha</title>
      <link>https://dev.to/vabelha</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/vabelha"/>
    <language>en</language>
    <item>
      <title>How to still use Crawlers in Client-Side Websites</title>
      <dc:creator>Vasco Abelha</dc:creator>
      <pubDate>Wed, 12 Aug 2020 11:57:32 +0000</pubDate>
      <link>https://dev.to/vabelha/how-to-still-use-crawlers-in-client-side-websites-41e3</link>
      <guid>https://dev.to/vabelha/how-to-still-use-crawlers-in-client-side-websites-41e3</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally this was published on my &lt;a href="https://vascoabelha.com/blog"&gt;blog&lt;/a&gt;. You can find the publication &lt;a href="https://vascoabelha.com/blog/how-to-use-crawlers-client-side-websites"&gt;here&lt;/a&gt;!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you wanna discuss anything feel free to reach me on &lt;a href="https://twitter.com/VaapVa"&gt;Twitter&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;In this post, I will describe a solution that I built for an already existing React Client-Side platform, in which people wanted to be able to share specific content on their feeds.&lt;/p&gt;

&lt;p&gt;This publication is useful for developers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;have an already built a Client-Side Website (doesn't need to be solely React)&lt;/li&gt;
&lt;li&gt;want to understand how we can interact with different crawlers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Technologies used:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;VPS where the project was hosted&lt;/li&gt;
&lt;li&gt;Nginx;&lt;/li&gt;
&lt;li&gt;ExpressJS (It doesn't matter what you are using).&lt;/li&gt;
&lt;li&gt;ReactJS&lt;/li&gt;
&lt;li&gt;Facebook SDK - OpenGraph&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Contextualization
&lt;/h1&gt;

&lt;p&gt;Whenever you share a link to a website in Facebook, Twitter, or any other social platform, they spawn a crawler that will scrape your website in order to look for meta tags that can help them understand what they are looking at and how they can share it - App, Card, Summary, Large Card, etcetera.&lt;/p&gt;

&lt;p&gt;One of the biggest problems in a React Client-Side website is that everything is rendered through JavaScript. If you use a Browser or a Crawler that doesn't process JS, you will just be presented with a &lt;strong&gt;blank page - You need to enable JavaScript to run this app.&lt;/strong&gt; This applies to Facebook or Twitter Crawlers.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1y7h5w81--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/fx140unoncvdz321apsa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1y7h5w81--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/fx140unoncvdz321apsa.png" alt="Example of Black Page"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the end, if you share an URL from your website on one of these social platforms, you won't get any type of card or information from your website. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; You can use &lt;a href="https://cards-dev.twitter.com/validator"&gt;https://cards-dev.twitter.com/validator&lt;/a&gt; to verify and test yourself.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--x6CdsTbW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/wsv9nd5ka4vgemp393yv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--x6CdsTbW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/wsv9nd5ka4vgemp393yv.png" alt="Twitter Card Validator"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To the Left we Have a React Client Side Website. To the Right we have a static website.&lt;/p&gt;

&lt;p&gt;In both Websites, I have React-Helmet (which allows modifications to your document head), yet the left side still shows no meta-tags fetched by the crawlers due to requiring JavaScript to render.&lt;/p&gt;

&lt;h1&gt;
  
  
  Show what the Crawlers want to see
&lt;/h1&gt;

&lt;p&gt;If we are hosting the website on a typical Virtual Private Server, then there is a good chance that we are using a web server like apache, nginx or lighttpd to process the incoming HTTP requests.&lt;br&gt;
Thus a web server like Nginx is the perfect place to "trick" him and proxy him into a renderer HTML with the information that we want the crawler to see.&lt;br&gt;
For this we need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To know which requests come from the crawlers;&lt;/li&gt;
&lt;li&gt;a service that renders Dynamic HTML Content;&lt;/li&gt;
&lt;li&gt;Update NGINX to link crawlers to the new service.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Crawlers Identification
&lt;/h2&gt;

&lt;p&gt;After researching Facebook and Twitter Documentation we can identify the crawlers by the following user-agent strings:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;facebookexternalhit/1.1&lt;/code&gt; (Facebook)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Twitterbot&lt;/code&gt;(Twitter)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Service to render Dynamic HTML
&lt;/h2&gt;

&lt;p&gt;You have other types of solutions. You can pretty much use anything that renders an HTML webpage.&lt;/p&gt;

&lt;p&gt;In this case, I had an already established set of services available through expressjs, so I stuck with it and created one endpoint that would take params (in this case a news publication identifier) and return an HTML page with every kind of head and meta tags that I wanted to be scraped by the crawlers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note: The URL must be equal to the one where I view the news publication.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Example of the service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;//(routes/social.js -&amp;gt; socialRoutes)&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/news/:id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;news&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;getNews&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text/html&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&amp;lt;!DOCTYPE html&amp;gt;
  &amp;lt;html&amp;gt;
        &amp;lt;head&amp;gt;
            &amp;lt;link rel="canonical" href="&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;news&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;" /&amp;gt;
            &amp;lt;meta property="og:title" content="&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;news&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;gt;" /&amp;gt;
            &amp;lt;meta property="og:description" content="&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;news&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;" /&amp;gt;
            &amp;lt;meta property="og:image" content="&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;news&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cover_image&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;" /&amp;gt;
            &amp;lt;meta property="og:url" content="&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;news&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;" /&amp;gt;
            &amp;lt;meta name="twitter:title" content="&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;news&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;gt;" /&amp;gt;
            &amp;lt;meta name="twitter:description" content="&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;news&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;" /&amp;gt;
            &amp;lt;meta name="twitter:image" content="&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;news&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cover_image&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;" /&amp;gt;
            &amp;lt;meta name="twitter:url" content="&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;news&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;" /&amp;gt;
            &amp;lt;meta name="twitter:card" content="summary" /&amp;gt;
        &amp;lt;/head&amp;gt;
  &amp;lt;/html&amp;gt;
`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;//server.js&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/social&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;socialRoutes&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;started at localhost:3500&lt;/span&gt;&lt;span class="dl"&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;h2&gt;
  
  
  Update NGINX and Send Crawlers to our Service
&lt;/h2&gt;

&lt;p&gt;With knowing the user-agent strings of the crawlers and having already defined our service to generate HTML pages free of javascript.&lt;br&gt;
We can now "trick" the crawlers with the help of NGINX and send them to our services instead of the real webpage.&lt;br&gt;
Usually, if you are using a react app under Nginx, your default.conf file will be generally similar to this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;server&lt;span class="o"&gt;{&lt;/span&gt;
    root /var/www/html&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c"&gt;# Add index.php to the list if you are using PHP&lt;/span&gt;
    index index.html index.htm index.nginx-debian.html&lt;span class="p"&gt;;&lt;/span&gt;

    server_name www.example.com example.com&lt;span class="p"&gt;;&lt;/span&gt;

    location / &lt;span class="o"&gt;{&lt;/span&gt;
        try_files &lt;span class="nv"&gt;$uri&lt;/span&gt; /index.html&lt;span class="p"&gt;;&lt;/span&gt; 
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Nevertheless, this isn't enough, because the crawlers will still go to our files located in root and only see blank pages due to javascript rendering.&lt;/p&gt;

&lt;p&gt;Therefore we need to add a prior condition to verify the user-agent before sending them to our project folder.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;server&lt;span class="o"&gt;{&lt;/span&gt;
    root /var/www/html&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c"&gt;# Add index.php to the list if you are using PHP&lt;/span&gt;
    index index.html index.htm index.nginx-debian.html&lt;span class="p"&gt;;&lt;/span&gt;

    server_name www.example.com example.com&lt;span class="p"&gt;;&lt;/span&gt;

    location / &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c"&gt;# Here we proxy the request to our api if user-agent matches any of these regular expressions&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$http_user_agent&lt;/span&gt; ~ facebookexternalhit|Twittterbot&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            proxy_pass http://localhost:3500/social&lt;span class="nv"&gt;$uri$args&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
        try_files &lt;span class="nv"&gt;$uri&lt;/span&gt; /index.html&lt;span class="p"&gt;;&lt;/span&gt; 
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Every time we have a new request that matches the user-agents of Facebook and Twitter, we will proxy it to our service for HTML rendering. Thus, in turn, allowing the crawlers to process our "not-so-real" webpage as the &lt;strong&gt;real&lt;/strong&gt; one and fetch the meta-tags needed to share our website.&lt;/p&gt;

&lt;p&gt;As long as you have some kind of middleware that can act as a reverse proxy, then you can still allow client-side web applications to be scraped by crawlers that don't execute javascript.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nevertheless, if possible you should take a look at Static Side Generators or Server-Side Rendering Frameworks.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This publication is only useful to shed some light on how you can interact with crawlers and to possibly guide or help someone in anything similar that they are working on.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>seo</category>
      <category>crawlers</category>
    </item>
    <item>
      <title>How to easily add HTTPS to your Server for free!</title>
      <dc:creator>Vasco Abelha</dc:creator>
      <pubDate>Tue, 04 Aug 2020 15:53:09 +0000</pubDate>
      <link>https://dev.to/vabelha/how-to-easily-add-https-to-your-server-for-free-2ec4</link>
      <guid>https://dev.to/vabelha/how-to-easily-add-https-to-your-server-for-free-2ec4</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally this was published on my &lt;a href="https://vascoabelha.com/blog"&gt;blog&lt;/a&gt;. You can find the publication &lt;a href="https://vascoabelha.com/blog/how-to-easily-add-https-server-free"&gt;here&lt;/a&gt;! If you wanna discuss anything feel free to reach me on my &lt;a href="https://twitter.com/VaapVa"&gt;Twitter&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Long gone are the days where if you wanted to have https, you had to pay out at least more 10$ for a certificate.&lt;/p&gt;

&lt;p&gt;Nowadays, if for any reason you are hosting a website or an API in your Virtual Private Server on AWS, DigitalOcean, and any other VPS Hosting; most likely you got a Linux distribution with a basic configuration and no SSL. Luckily, now we have Let's Encrypt Me! 🥳&lt;/p&gt;

&lt;p&gt;In this publication, I will:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;succinctly explain what is SSL, TLS.&lt;/li&gt;
&lt;li&gt;Explain how you can create your digital cert and install it on the webserver that you are most likely using - Nginx or Apache.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;To try to help the most people I can, this guide will only be focused on Ubuntu. If you need any help feel free to reach me here or through Twitter! Same reason for Lighttpd&lt;/em&gt; ❤️&lt;/p&gt;

&lt;p&gt;A refresher on terminology:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SSL -&lt;/strong&gt; Secure Sockets Layer is a cryptographic protocol responsible for encrypting data (secure connections) between a client and a server.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TLS&lt;/strong&gt; - Transport Layer Security  is also a cryptographic protocol responsible for encrypting data and securing connections between endpoints.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The main difference is that TLS is an &lt;strong&gt;updated&lt;/strong&gt; version of SSL with stronger encryption algorithms like RSA, DSA, etc. &lt;/p&gt;

&lt;p&gt;So whenever you are talking or see something saying anything regarding SSL, they are probably referring to TLS.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's Encrypt Me
&lt;/h2&gt;

&lt;p&gt;Let's Encrypt me is a non-profitable certificate authority (CA) that easily provides  SSL/TLS certificates for free and public use. It is run by the Internet Security Research Group (ISRG).&lt;/p&gt;

&lt;p&gt;In layman terms, through ACME protocol, they can easily verify that you own your domain and automatically issue digital certs that you can use to enable https for your websites or applications.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Certbot&lt;/strong&gt; is the software used to validate your domain and request the digital certificates to be installed on your server.&lt;/p&gt;

&lt;h3&gt;
  
  
  Add Certbot repository to Ubuntu.
&lt;/h3&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;add-apt-repository ppa:certbot/certbot
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Depending on the software that you are using, it might be preferable to check for working repositories, because default repositories provided by your Distro could be outdated.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Install Certbot Package
&lt;/h3&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;//If you have apache
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;python-certbot-apache 

//If you have nginx
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;python-certbot-nginx
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Execute Cerbot
&lt;/h3&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;//If you have apache
&lt;span class="nb"&gt;sudo &lt;/span&gt;certbot &lt;span class="nt"&gt;--apache&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; vascoabelha.com &lt;span class="nt"&gt;-d&lt;/span&gt; www.vascoabelha.com

//If you have nginx
&lt;span class="nb"&gt;sudo &lt;/span&gt;certbot &lt;span class="nt"&gt;--nginx&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; vascoabelha.com &lt;span class="nt"&gt;-d&lt;/span&gt; www.vascoabelha.com
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Instead of &lt;a href="http://vascoabelha.com"&gt;vascoabelha.com&lt;/a&gt;, here you need to make reference to the name that you defined in your web server configuration, either on: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;/etc/apache2/sites-available/[domain].conf  (ServerName)&lt;/li&gt;
&lt;li&gt;/etc/nginx/sites-available/&lt;a href="https://dev.toserver_name"&gt;domain&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If it is the first time you are running on your host, you will need to answer some questions. (nothing to worry about)&lt;/p&gt;

&lt;p&gt;In the end, you will be presented with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;Please&lt;/span&gt; &lt;span class="nx"&gt;choose&lt;/span&gt; &lt;span class="nx"&gt;whether&lt;/span&gt; &lt;span class="nx"&gt;or&lt;/span&gt; &lt;span class="nx"&gt;not&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;redirect&lt;/span&gt; &lt;span class="nx"&gt;HTTP&lt;/span&gt; &lt;span class="nx"&gt;traffic&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;HTTPS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;removing&lt;/span&gt; &lt;span class="nx"&gt;HTTP&lt;/span&gt; &lt;span class="nx"&gt;access&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;No&lt;/span&gt; &lt;span class="nx"&gt;redirect&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;Make&lt;/span&gt; &lt;span class="nx"&gt;no&lt;/span&gt; &lt;span class="nx"&gt;further&lt;/span&gt; &lt;span class="nx"&gt;changes&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;webserver&lt;/span&gt; &lt;span class="nx"&gt;configuration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Redirect&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;Make&lt;/span&gt; &lt;span class="nx"&gt;all&lt;/span&gt; &lt;span class="nx"&gt;requests&lt;/span&gt; &lt;span class="nx"&gt;redirect&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;secure&lt;/span&gt; &lt;span class="nx"&gt;HTTPS&lt;/span&gt; &lt;span class="nx"&gt;access&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nx"&gt;Choose&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;sites&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;or&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nx"&gt;you&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;re confident your site works on HTTPS. You can undo this
change by editing your web server&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="nx"&gt;configuration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;
&lt;span class="nx"&gt;Select&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;appropriate&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="nx"&gt;then&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;enter&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;press&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;c&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;cancel&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;I tend to always select number 2. Certbot will then change your Nginx/Apache configuration to add the needed redirects (301) to force your connections to https.&lt;/p&gt;

&lt;p&gt;By now, you will have your certs installed and running. If you refresh your website, you will see the shiny 🔒 followed up by https  🥳!!&lt;/p&gt;

&lt;h2&gt;
  
  
  👏Everything is set and running👏
&lt;/h2&gt;

&lt;p&gt;Last but not least, these certificates are valid for 90 days! Yet you don't need to worry, Certbot runs twice a day and will make sure your certificate is valid and issues another one if needed (less than 30 days of validity).&lt;/p&gt;

&lt;p&gt;If you would like to test if the certification refresh process is working fine, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;certbot renew &lt;span class="nt"&gt;--dry-run&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;If in step 3, you provided a real email, you will also be notified in case the renewal process fails!&lt;/p&gt;

&lt;p&gt;See you around!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>codenewbie</category>
      <category>security</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Simplify the development  of Portfolio Website by planning your Stack and Design</title>
      <dc:creator>Vasco Abelha</dc:creator>
      <pubDate>Wed, 22 Jul 2020 10:40:44 +0000</pubDate>
      <link>https://dev.to/vabelha/simplify-the-development-of-portfolio-website-by-planning-your-stack-and-design-3i25</link>
      <guid>https://dev.to/vabelha/simplify-the-development-of-portfolio-website-by-planning-your-stack-and-design-3i25</guid>
      <description>&lt;p&gt;Hey everyone! 👋&lt;/p&gt;

&lt;p&gt;This is my first post ever and I know that this is just another drop in the ocean of guides in "how to build your own webpage/portfolio". &lt;br&gt;
Nevertheless, I hope that I can shed a different light and approach in the planning of your portfolio. This is also for me a first step in giving back to the dev community, the help and guidance I have received so far.&lt;/p&gt;

&lt;h1&gt;
  
  
  Context
&lt;/h1&gt;

&lt;p&gt;Over the last month, I have built my personal website and tried to keep it simple but aesthetically pleasing. &lt;/p&gt;

&lt;p&gt;During the development, I documented every decisions and steps I made in order to help me solidify some concepts. Since there are already many and good guides in how to build portfolios, I will abstain from delving in coding breakdown/guides and will focus on a more generic perspective. Besides I don't think it would be valuable for the reader to be imposed with a design and code that he is not comfortable with. Our personal/portfolios websites should be a representation of ourselves, preferences and likes.&lt;/p&gt;

&lt;p&gt;In this post, I will describe what I used for building my webpage (JAMStack) and reasons for choosing this architecture. There will also be a short section regarding the design of your website and some tips to help you stand out!&lt;/p&gt;

&lt;h1&gt;
  
  
  So why JAMStack?
&lt;/h1&gt;

&lt;p&gt;My decision with going with JAMStack can be quickly summarized in wanting:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A Fast, Cheaper,  Secured and Simpler way of developing and maintaining a website. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Xu5n5rI2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/cowh6lutf7ud8chtufel.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Xu5n5rI2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/cowh6lutf7ud8chtufel.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;JAMStack is a term used to describe a new architecture for building websites and applications where&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;JAM → J = JavaScript | A = API | M = Markup&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  JavaScript
&lt;/h2&gt;

&lt;p&gt;JavaScript role is building dynamic content on your website, fetching data, etc. This does not mean that everything in a JAMStack is built with Javascript. &lt;br&gt;
In fact, you have different SSG (Static Site Generators) built on different languages. Eg: Hugo in Golang, Jekyll in Ruby, Pelican in Python, etc. &lt;/p&gt;

&lt;p&gt;For a list of available SSG you can go to: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.staticgen.com/"&gt;https://www.staticgen.com/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  API
&lt;/h2&gt;

&lt;p&gt;Where usually we have Server-side functions to access/consume/query data, in JAMStack these API/services are accessed and consumed as you want. JAMStack is agnostic to API. We can easily use 3rd party services as well as building our own specific APIs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Markup
&lt;/h2&gt;

&lt;p&gt;This is where the fun is! Everything that you see in your site is served through HTML Static Files created during the building phase. These files have already the structure and information needed to be presented when accessing the page. &lt;/p&gt;

&lt;p&gt;Unlike dynamic website based on templates, you don't need to wait for the server to query the api/database to present and render the webpage, since the website and its respective pages were prebuilt at the time of the build. The frontend is decoupled from the backend and thus the website can "live on its own" -  serverless.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--q_bdVQkA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9am30hkx4lfoxubt48sv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--q_bdVQkA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/9am30hkx4lfoxubt48sv.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the end, we  have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A more secure website since it does not need to interact with a backend;&lt;/li&gt;
&lt;li&gt;Faster and more responsive website since everything is built on static html files, we don't need to query or wait for anyone to render the page;&lt;/li&gt;
&lt;li&gt;Scalable due to the CDN (Content Delivery Network) for the website and the strict separation/modularity, between frontend/website and backend;&lt;/li&gt;
&lt;li&gt;Cheaper because you have companies that can even host your static files for free!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With this in mind, and after checking the available static site generators, I ended up choosing the &lt;strong&gt;GatsbyJS&lt;/strong&gt; due to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;better SEO features;&lt;/li&gt;
&lt;li&gt;documentation - this was a decisive factor. Gatsby.JS documentation is clear and more than sufficient to guide you in every step of the way, from preparing, developing, to building and deploying a website;&lt;/li&gt;
&lt;li&gt;larger dev community, in which can be seen as: "I will most likely fail somewhere, but at least I have a higher chance of finding someone that had the same problem" 😂.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Setting aside the technological decisions, we can now focus on a more subjective and personal based decision - the design.&lt;/p&gt;

&lt;h1&gt;
  
  
  Design
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Choosing between templates or designing yourself.
&lt;/h2&gt;

&lt;p&gt;Like many of you, I am not a designer or specialised in any kind of UI/UX.  Everything that I know is from self-learning and probably not much 😬. However, we can't be hostage of our own shortcomings, so what can we do to fill the gaps?&lt;/p&gt;

&lt;p&gt;Well we can either use an already built template/theme available 😞 or we can do some research on what does a good design entails and view some examples as inspiration 🤩. &lt;/p&gt;

&lt;p&gt;Here is a list of some good websites/resources that I tend to use when I am in need of inspiration:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://dribbble.com/"&gt;https://dribbble.com/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://webframe.xyz/"&gt;https://webframe.xyz/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://land-book.com/"&gt;https://land-book.com/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.behance.net/"&gt;https://www.behance.net/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.designnotes.co/"&gt;https://www.designnotes.co/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://edu.gcfglobal.org/en/beginning-graphic-design/"&gt;https://edu.gcfglobal.org/en/beginning-graphic-design/&lt;/a&gt; (I believe this is a good tutorial to help you grasp some of the basic concepts of graphic design)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now if you ask me if I would use a theme/template or build one from scratch, I would undoubtedly choose the latter, due to the fact that I believe in the importance of showing ourselves, our uniqueness through what we design and build. Even though a prebuilt template would most likely save me time, I tend to see everything that I do as an opportunity to invest in myself and learn new things and comparing both options I probably wouldn't learn a lot with using a template.&lt;/p&gt;

&lt;h2&gt;
  
  
  Things to take in consideration during the design and development.
&lt;/h2&gt;

&lt;p&gt;Before coding, I would advise you to create some Mockups of your website. This will not only force you to organise your ideas on what and how do you want to show, but also help delineate a plan, a series of steps needed to effectively assist and guide you during the coding sessions. &lt;br&gt;
For this you can use tools like Figma, Adobe XD, Sketch, etc.&lt;/p&gt;

&lt;p&gt;Here are some tips to help you start designing your portfolio/personal websites:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fonts play an important role. It sets the tone of your design. If you are stuck in choosing a pair of fonts with good contrast for your website, you could use a tool like &lt;a href="https://fonts.google.com/"&gt;https://fonts.google.com/&lt;/a&gt; or &lt;a href="https://fontjoy.com/"&gt;https://fontjoy.com/&lt;/a&gt; to help you decide.&lt;/li&gt;
&lt;li&gt;In terms of colours, you will probably be fine with 2-3 colours that work well together. If you are interested in learning more, you can search for colour theory. There are also websites that help you building pallets of colours like : &lt;a href="http://colormind.io/"&gt;http://colormind.io/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;On top of linking your social media, a Contact Form is also an important tool to build bridges between you and your visitors. Nowadays, depending on the stack that you are using, it is super simple to build and deploy a reasonable Contact Form -  E.g. Netlify Forms and Formspree.&lt;/li&gt;
&lt;li&gt;In addition to publishing your work in the website, you should also have a hyperlink to a detailed CV. This may speed and ease the process of recruiters or agencies that are searching for candidates, and if they end up in your website, then you are probably a suitable candidate for what they are searching 🤔&lt;/li&gt;
&lt;li&gt;This isn't  related to design, but if you have the possibility, you should buy a domain. Having a custom domain name will improve your credibility and professionalism in the eyes of the visitors.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;For this post, I have covered everything that I wanted:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JAMStack;&lt;/li&gt;
&lt;li&gt;Decisions that made me choose a JAMStack Architecture and GatsbyJS;&lt;/li&gt;
&lt;li&gt;Resources to help you start designing your website;&lt;/li&gt;
&lt;li&gt;What approach to have when building your portfolio in order to stand out, save time and reduce indecisiveness → No Templates, Mockups First and Code later;&lt;/li&gt;
&lt;li&gt;General tips to take in consideration while designing and building your portfolio.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If there is interest, I can follow-up this post, with one more focused on a review of the existing CSS Frameworks and what I ended up choosing, as well as SEO explanation and guide to help boost the visibility of your webpage.&lt;/p&gt;

&lt;p&gt;If you wanna chat or discussing anything feel free to reach me at &lt;a href="https://twitter.com/VaapVa"&gt;Twitter&lt;/a&gt; !&lt;/p&gt;

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

</description>
      <category>webdev</category>
      <category>portfolio</category>
      <category>career</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
