<?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: Romeo Mihalcea</title>
    <description>The latest articles on DEV Community by Romeo Mihalcea (@ciokan).</description>
    <link>https://dev.to/ciokan</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%2F125581%2Fc279b4a5-9a4c-4626-8840-a0bcfd6441e1.jpeg</url>
      <title>DEV Community: Romeo Mihalcea</title>
      <link>https://dev.to/ciokan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ciokan"/>
    <language>en</language>
    <item>
      <title>Create your own WireGuard server in minutes</title>
      <dc:creator>Romeo Mihalcea</dc:creator>
      <pubDate>Sat, 21 Nov 2020 16:04:50 +0000</pubDate>
      <link>https://dev.to/ciokan/create-your-own-wireguard-server-in-minutes-1i4f</link>
      <guid>https://dev.to/ciokan/create-your-own-wireguard-server-in-minutes-1i4f</guid>
      <description>&lt;p&gt;With the rise in privacy concerns over tech giants battling for our data I thought it would be fit to have a small talk about creating your own VPN server. Now I know there are countless of other tutorials out there but there's never enough attention over this subject.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is WireGuard
&lt;/h3&gt;

&lt;p&gt;WireGuard is the new kid, the much needed tool in the VPN world to bring everything to the next step. It is a small, fast and effective new VPN protocol that stormed everything since its early days. Very quickly it received great reviews for its performance and it is now included in the new Kernels for Linux and Android. I don't recall ever hearing about any other library to be included so fast in the Kernel so that says a lot I guess.&lt;/p&gt;

&lt;p&gt;Wireguard is much leaner and faster when compared with other protocols and this makes it the preferred choice for many. How much faster? You can read our &lt;a href="https://nologs-vpn.com/wireguard-versus-openvpn"&gt;Wireguard vs OpenVPN&lt;/a&gt; article to see a comparison of the two.&lt;/p&gt;

&lt;h3&gt;
  
  
  How much does it cost to own my VPN server
&lt;/h3&gt;

&lt;p&gt;Not much at all - with as much as $5 you can get a good VPS that can host a VPN server which handles the traffic for your entire family without breaking a sweat. Creating a server used to be a challenge but now, you can do it in 2 minutes. I suggest having a look at Digitalocean, Linode, Hetzner Cloud and others alike. Plenty of options.&lt;/p&gt;

&lt;h3&gt;
  
  
  My own server vs a VPN plan
&lt;/h3&gt;

&lt;p&gt;Simply because we cannot trust anybody. Most of the VPN providers have to abide the law which in many cases imposes that logs are kept and offered to gov. institutions for analyzing. We're trying to avoid being processed and analysed at every move so, sending our entire data stream to a VPN provider is nothing more than just adding an extra hop in the same chain.&lt;/p&gt;

&lt;p&gt;Having your own VPN server will break this chain and put a stop to the leak of data that we experience with ISPs or VPN providers and the process is simple. You can either let others &lt;a href="https://nologs-vpn.com"&gt;create a secure VPN server&lt;/a&gt; for you or build it yourself following guides like this one.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to create a WireGuard server
&lt;/h2&gt;

&lt;p&gt;First of all, WireGuard does not have the notion of "servers". Everything is a &lt;code&gt;peer&lt;/code&gt; and peers are connected with one another. The config files consist of 2 parts: an &lt;code&gt;[Interface]&lt;/code&gt; which addresses the local instructions and multiple &lt;code&gt;[Peer]&lt;/code&gt; sections which define remote connections.&lt;/p&gt;

&lt;h3&gt;
  
  
  What operating system to use?
&lt;/h3&gt;

&lt;p&gt;I recommend Debian, the latest you can find with the selected provider. I will use Debian 10 (Buster) for this tutorial.&lt;/p&gt;

&lt;p&gt;The first thing to do is to go ahead and add the Wireguard release channel to your sources list. The sources are like search channels for software and, without them, your operating system cannot find anything:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;sh &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"echo 'deb http://deb.debian.org/debian/ unstable main' &amp;gt;&amp;gt; /etc/apt/sources.list.d/unstable.list"&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;sh &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"printf 'Package: *&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;Pin: release a=unstable&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;Pin-Priority: 90&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;' &amp;gt;&amp;gt; /etc/apt/preferences.d/limit-unstable"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now issue an &lt;code&gt;apt update&lt;/code&gt; command to re-fetch the sources and we should be able to install Wireguard with &lt;code&gt;apt install wireguard&lt;/code&gt;. &lt;/p&gt;

&lt;h3&gt;
  
  
  [SERVER] Create your keys
&lt;/h3&gt;

&lt;p&gt;Peers connect via IP addresses but they have to authenticate before a connection can be established. Keys come in pairs (public and private) and each peer must know the other peers beforehand which means writing down to the config file the public key for each peer.&lt;/p&gt;

&lt;p&gt;With the install of Wireguard we now have access to the &lt;code&gt;wg&lt;/code&gt; and &lt;code&gt;wg-quick&lt;/code&gt; commands which allows us to create our keys:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;umask &lt;/span&gt;077 &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; wg genkey &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; wg-private.key&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;wg pubkey &amp;lt; wg-private.key &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; wg-public.key
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you run &lt;code&gt;ls -la&lt;/code&gt; you will see the keys have been created. You can also run &lt;code&gt;cat wg-private.key&lt;/code&gt; to view the contents of each file.&lt;/p&gt;

&lt;h3&gt;
  
  
  [SERVER] Create the config file
&lt;/h3&gt;

&lt;p&gt;Now that we have the keys we are almost done setting up the server. We have to create the config file and bring up the VPN interface that will listen on the selected port.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;/etc/wireguard/wg0.conf&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Interface]
Address = 10.10.10.1/24
ListenPort = 51820
PrivateKey = server+private+key+here
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE; ip6tables -A FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE; ip6tables -D FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The only thing you have to change here is the &lt;code&gt;eth0&lt;/code&gt; interface name. On some systems it may have a different name. To get yours you can execute this handy command: &lt;code&gt;route | grep '^default' | grep -o '[^ ]*$'&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We have created the server config but haven't added any peers yet. That's because we need to generate the keys for the client now so we can add them to our peers list. The server will listen on the private address &lt;code&gt;10.10.0.1&lt;/code&gt;. You may be wondering what is the purpose of the public key because we haven't used it yet. It will be added to the client config in our next steps.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;PostUp&lt;/code&gt; and &lt;code&gt;PostDown&lt;/code&gt; instructions are executed when the server is started and stopped and they enable IP forwarding so that you can exchange packets with your server. IP forwarding must also be enabled on the server by editing the &lt;code&gt;*/etc/sysctl.conf&lt;/code&gt; file and adding:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;net.ipv4.ip_forward=1
net.ipv6.conf.all.forwarding=1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  [CLIENT] Create keys
&lt;/h3&gt;

&lt;p&gt;We also need the client keys so we can add authenticated peers to the server. Repeat the steps from the server in order to generate keys but this time on the local machine. If you're on windows or MacOS you can download the Wireguard gui package and copy the keys from there.&lt;/p&gt;

&lt;h3&gt;
  
  
  [CLIENT] Create config file
&lt;/h3&gt;

&lt;p&gt;Once you have the keys we can create the local configuration file:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;/etc/wireguard/wg0.conf&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Interface]
Address = 10.10.10.2/24
PrivateKey = client+private+key+here
DNS = 10.10.10.1

[Peer]
AllowedIPs = 0.0.0.0/0
Endpoint = server_ip_address:51820
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our client config is done. It has a local description (&lt;code&gt;[Interface]&lt;/code&gt;), it will be allocated the &lt;code&gt;10.10.10.2&lt;/code&gt; address, that's the next address after the server and it also forwards dns queries to the server.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;[Peer]&lt;/code&gt; in this case is the server so, before attempting a connection, we also add a peer to the server that contains our public key otherwise our connection will be refused.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;/etc/wireguard/wg0.conf&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Interface]
Address = 10.10.10.1/24
ListenPort = 51820
PrivateKey = server+private+key+here

[Peer]
PublicKey = client+public+key+here
AllowedIPs = 10.10.10.2/32
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Time to bring up the server: &lt;code&gt;wg-quick up wg0&lt;/code&gt;. &lt;br&gt;
To bring it up automatically after restart (at boot): &lt;code&gt;systemctl enable wg-quick@wg0&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Connect to the server
&lt;/h3&gt;

&lt;p&gt;With all peers defined and keys ready to be exchanged it is now time to connect to our server. Remember that wireguard is stateless and it will probably report a successful connection even though it is not. You should test your IP address, dns leaks and other stuff to verify the connection was made.&lt;/p&gt;

</description>
      <category>wireguard</category>
      <category>vpn</category>
      <category>privacy</category>
    </item>
    <item>
      <title>CNAME cloaking or how are we being tracked even with ad-blockers installed</title>
      <dc:creator>Romeo Mihalcea</dc:creator>
      <pubDate>Mon, 09 Mar 2020 15:47:24 +0000</pubDate>
      <link>https://dev.to/dnsadblock/cname-cloaking-or-how-are-we-being-tracked-even-with-ad-blockers-installed-5ok</link>
      <guid>https://dev.to/dnsadblock/cname-cloaking-or-how-are-we-being-tracked-even-with-ad-blockers-installed-5ok</guid>
      <description>&lt;p&gt;For many years we relied on regular ad blockers to clean our screen from ads, trackers and other junk but there's a way that these websites use to bypass our efforts and it works very well.&lt;/p&gt;

&lt;p&gt;Regular ad blockers intercept your browser's requests and analyze each one to see if there are matching rules against it. The flaw is in this technique because the extension only has access to the first party (the requested url) without being able to monitor what is taking place once a request does not match any of its rules - at the DNS level for example.&lt;/p&gt;

&lt;p&gt;In this post I'm going to explain how one can mask/cloak a tracking domain behind some DNS trickery, bypassing browser based ad-blockers. It takes only a few minutes to buy a new domain and setup a &lt;code&gt;CNAME&lt;/code&gt; alias to achieve this masking technique so it is very easy.&lt;/p&gt;

&lt;p&gt;A &lt;code&gt;CNAME&lt;/code&gt; is a domain that points to another domain, an alias. You can think of it as a permanent redirect but executed at the DNS level. Many tools rely on CNAMEs to serve content and I'm going to pick Netlify as an example here. Our blog is hosted on Netlify. Each deployed website is assigned a unique subdomain in the form of &lt;code&gt;unique-subdomain.netlify.com&lt;/code&gt;. In our case it is &lt;code&gt;festive-nobel-876c06.netlify.com&lt;/code&gt; and you can try it in your browser to see it works.&lt;/p&gt;

&lt;p&gt;If you want to use your own domain (of course you are) for this address (&lt;code&gt;blog.dnsadblock.com&lt;/code&gt;) you need to point it to &lt;code&gt;festive-nobel-876c06.netlify.com&lt;/code&gt; using a CNAME.&lt;/p&gt;

&lt;p&gt;Presuming that &lt;code&gt;festive-nobel-876c06.netlify.com&lt;/code&gt; is serving some tracking scripts and it is being blocked by ad blocking extensions I can simply alias a new domain to it and import the script using it:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;script src="https://blog.dnsadblock.com/itrackyou.js"&amp;gt;&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Since &lt;code&gt;festive-nobel-876c06.netlify.com&lt;/code&gt; appears only after the request was allowed (when the DNS is being resolved) it will pass without issues:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$: dig blog.dnsadblock.com

;; ANSWER SECTION:
blog.dnsadblock.com.    103 IN  CNAME   festive-nobel-876c06.netlify.com.
festive-nobel-876c06.netlify.com. 20 IN A   157.230.120.63
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;So how can we combat these techniques? Are ad-blockers dead? Not really. I know they are trying hard to kill or limit ad-blockers but they are still effective. The solution is to combine multiple tools. Our &lt;a href="https://dnsadblock.com"&gt;ad blocking DNS servers&lt;/a&gt; are monitoring and testing rules against CNAME aliases as well so this technique won't fly.&lt;/p&gt;

&lt;p&gt;If you are curious to see just how much tracking takes place on a regular machine have a look at this screenshot. This is my computer and I'm using dnsadblock only on it. This screenshot only reflects my activity and you can also see periods of inactivity when I'm testing other DNS servers so the numbers could be higher.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DYjffAId--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.dnsadblock.com/images/uploads/screenshot-dnsadblock.com-2020.03.02-19_18_47.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DYjffAId--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.dnsadblock.com/images/uploads/screenshot-dnsadblock.com-2020.03.02-19_18_47.png" alt="dnsadblock blocked requests"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>adblock</category>
      <category>dnsadblock</category>
      <category>blockads</category>
      <category>blocktracking</category>
    </item>
    <item>
      <title>Deploy a blazing-fast, feature-rich and free to use website with a blog in under 10 minutes</title>
      <dc:creator>Romeo Mihalcea</dc:creator>
      <pubDate>Thu, 03 Jan 2019 02:39:10 +0000</pubDate>
      <link>https://dev.to/ciokan/deploy-a-blazing-fast-feature-rich-and-free-to-use-website-with-a-blog-in-under-10-minutes-1e9a</link>
      <guid>https://dev.to/ciokan/deploy-a-blazing-fast-feature-rich-and-free-to-use-website-with-a-blog-in-under-10-minutes-1e9a</guid>
      <description>&lt;p&gt;2018 was a great year for me as a developer. I managed to put together an open-source project (still under heavy development) that was sitting on the back of my mind for many years.&lt;/p&gt;

&lt;p&gt;I don't know about you but, as a programmer that is comfortable with both the backend and frontend, I'm always testing new ideas, apps and websites. Doing so for years and years I noticed a repetitive task that was getting quite annoying. Each of my projects required a presentation website with a blog where I get to talk about it in more detail.&lt;/p&gt;

&lt;p&gt;That means at least one web server with a database attached. It's not hard but takes a lot of time that I would rather spend on something else instead so I stopped and brainstormed my next project that would end this repetitive cycle of costly deployments.&lt;/p&gt;

&lt;h2&gt;
  
  
  Every good house starts with a strong foundation
&lt;/h2&gt;

&lt;p&gt;My framework of choice was Gatsby. It had most of the things that I would consider to be required:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;it has to compile to static files&lt;/li&gt;
&lt;li&gt;easy to deploy to a CDN such as Netlify&lt;/li&gt;
&lt;li&gt;image optimization in place&lt;/li&gt;
&lt;li&gt;vibrant community&lt;/li&gt;
&lt;li&gt;hackable because I like to get my hands dirty&lt;/li&gt;
&lt;li&gt;extensible via plugins&lt;/li&gt;
&lt;li&gt;uses GraphQl to fetch data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6mBtkPus--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/razqzt3omu8kac5egf8v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6mBtkPus--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/razqzt3omu8kac5egf8v.png" alt="Fast deployments"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    query($slug: String, $tags: [String], $categories: [String]) {
        post: markdownRemark(fields: { slug: { eq: $slug } }) {
            ...postFragment
        }
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result had to be something oriented towards programmers. I hate wysiwyg editors with a passion because there are many constraints and the output never seems to be predictable. I wanted something where I put the power of the framework at reach for both the developer and content editor.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--E3rydTqD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/92bys8ygfhfofvpgtt2n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--E3rydTqD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/92bys8ygfhfofvpgtt2n.png" alt="Power to the publishers"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Developers and Publishers express without barriers
&lt;/h2&gt;

&lt;p&gt;Slowly but surely &lt;a href="https://www.qards.io"&gt;Qards&lt;/a&gt; took shape. My goal was to give more power to the writer by using, what I like to call, "smart cards". The content editor should be able to create interactive presentations using widgets that respond to events, to dates, to browser types, regions or any other external factors that can be made available to a frontend engineer. Some of those widgets include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;automatically generated toc (table of contents) (developed)&lt;/li&gt;
&lt;li&gt;charts (planned)&lt;/li&gt;
&lt;li&gt;accordions (developed)&lt;/li&gt;
&lt;li&gt;images (developed)&lt;/li&gt;
&lt;li&gt;galleries (developed)&lt;/li&gt;
&lt;li&gt;video embeds (developed)&lt;/li&gt;
&lt;li&gt;audio playlist (developed)&lt;/li&gt;
&lt;li&gt;code blocks (developed)&lt;/li&gt;
&lt;li&gt;callouts (developed)&lt;/li&gt;
&lt;li&gt;countdowns (developed)&lt;/li&gt;
&lt;li&gt;grid lists (planned)&lt;/li&gt;
&lt;li&gt;references to other posts (developed)&lt;/li&gt;
&lt;li&gt;etc&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kLpVcLJy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/cqgjevdoxtjy077nsyva.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kLpVcLJy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/cqgjevdoxtjy077nsyva.png" alt="Smart cards"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One other must-have for such a platform was the ability to add custom widgets via an internal plugin system (still under development/planned). The developer creates directives and data requirements which are interpreted by the admin interface (Netlify CMS) where the content publisher is able to create those experiences. That's right, let's navigate from simple posts to "experiences" for our visitors. We're all affected by bounce rates that connect directly with dull interfaces.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's get the word out
&lt;/h2&gt;

&lt;p&gt;One month later into the project I had a clear path and an idea that was no longer just a blurry shape. I like to test such things before an official launch by putting it out there on ProductHunt and other similar platforms.&lt;/p&gt;

&lt;p&gt;Qards was quickly picked-up and got to 2nd place for that day which was not bad at all for something which was not even in an alpha stage.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--813XXIZI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/vmsnn5fbzqsm5axbshdz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--813XXIZI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/vmsnn5fbzqsm5axbshdz.png" alt="Qards on ProductHunt"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The feedback was more than helpful and my mailing list reached 2,000+ in one night so it was a productive experience for me. That's everything I needed to validate my project. I was going to use it anyway but I wasn't sure if I could make something for the general public out of it.&lt;/p&gt;

&lt;h2&gt;
  
  
  More than just a blog
&lt;/h2&gt;

&lt;p&gt;I may be advertising a blog but Qards is more than that. Being powered by Gatsby, it can be your next big project...with a blog. You simply get the added benefit of not having to worry about content any more.&lt;/p&gt;

&lt;h2&gt;
  
  
  In summary
&lt;/h2&gt;

&lt;p&gt;In summary I would like to recap everything that Qards is and does so here's a list of all the parts that make this project work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;powered by Gatsby and Netlify CMS, comes with all benefits&lt;/li&gt;
&lt;li&gt;free to use and free to deploy to Netlify or other CNDs (free SSL as well)&lt;/li&gt;
&lt;li&gt;rich, interactive widgets to keep your readers engaged&lt;/li&gt;
&lt;li&gt;more power to the content editors (think of it like Bootstrap for publishers)&lt;/li&gt;
&lt;li&gt;compiles to static files&lt;/li&gt;
&lt;li&gt;offline support&lt;/li&gt;
&lt;li&gt;pluggable&lt;/li&gt;
&lt;li&gt;extensible&lt;/li&gt;
&lt;li&gt;hackable&lt;/li&gt;
&lt;li&gt;free to use and develop with 0 restrictions

&lt;ul&gt;
&lt;li&gt;code/content sits on Github or Gitlab&lt;/li&gt;
&lt;li&gt;static files are served by any CDN you can think of&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;open source&lt;/li&gt;
&lt;li&gt;tested (work in progress)&lt;/li&gt;
&lt;li&gt;developer oriented&lt;/li&gt;
&lt;li&gt;developed in Typescript&lt;/li&gt;
&lt;li&gt;blazing fast&lt;/li&gt;
&lt;li&gt;appealing default design&lt;/li&gt;
&lt;li&gt;themable&lt;/li&gt;
&lt;li&gt;deployable and ready to publish in under 10 minutes&lt;/li&gt;
&lt;li&gt;markdown content&lt;/li&gt;
&lt;li&gt;progressive loading, image optimization and lazy loading of content&lt;/li&gt;
&lt;li&gt;un-hackable, always on production deployments&lt;/li&gt;
&lt;li&gt;awesome performance index&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If I managed to spark your interest please have a look at &lt;a href="https://www.qards.io/list-of-supported-cards/"&gt;Some of the supported cards&lt;/a&gt; to get a feel of what this project can do for you.&lt;/p&gt;

&lt;p&gt;Also, it's still an early phase so AMA and feel free to suggest new things.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>gatsby</category>
      <category>react</category>
      <category>typescript</category>
    </item>
  </channel>
</rss>
