<?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: Art Rosnovsky</title>
    <description>The latest articles on DEV Community by Art Rosnovsky (@rosnovsky).</description>
    <link>https://dev.to/rosnovsky</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%2F123386%2Fd08c9a99-2bef-46c8-9cae-e934cdd2eb06.jpeg</url>
      <title>DEV Community: Art Rosnovsky</title>
      <link>https://dev.to/rosnovsky</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rosnovsky"/>
    <language>en</language>
    <item>
      <title>Exploring Astro DB</title>
      <dc:creator>Art Rosnovsky</dc:creator>
      <pubDate>Wed, 13 Mar 2024 19:16:00 +0000</pubDate>
      <link>https://dev.to/rosnovsky/exploring-astro-db-2d89</link>
      <guid>https://dev.to/rosnovsky/exploring-astro-db-2d89</guid>
      <description>&lt;h2&gt;
  
  
  Astro DB
&lt;/h2&gt;

&lt;p&gt;Yesterday, the &lt;a href="https://astro.build"&gt;Astro&lt;/a&gt; team announced &lt;a href="https://astro.build/db/"&gt;Astro DB&lt;/a&gt; and &lt;a href="https://docs.astro.build/en/recipes/studio/"&gt;Astro Studio&lt;/a&gt;. Astro DB is a fully-managed SQL database integrated directly with the framework, and Astro Studio is a hosted interface to Astro DB. Personally, I find this development significant for a few reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Astro becomes more "batteries included"&lt;/li&gt;
&lt;li&gt;Local DX involving running a local database gets much easier&lt;/li&gt;
&lt;li&gt;It's just SQL so you can take it out at any moment and move to any other DB provider. The package for working with Astro DB, &lt;a href="https://www.npmjs.com/package/@astrojs/db"&gt;@astrojs/db&lt;/a&gt;, includes &lt;a href="https://orm.drizzle.team/"&gt;Drizzle ORM&lt;/a&gt; so migration to a different provider should be relatively painless&lt;/li&gt;
&lt;li&gt;Astro DB's free tier is generous but not &lt;em&gt;outrageously&lt;/em&gt; so (yes, it's a jab at &lt;a href="https://planetscale.com/blog/planetscale-forever"&gt;PlanetScale&lt;/a&gt;, I'm still salty); paid usage is &lt;em&gt;very&lt;/em&gt; reasonably priced&lt;/li&gt;
&lt;li&gt;It's easier than ever to add "advanced" dynamic features to static sites&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You may have a different set of reasons why it's worth talking about Astro DB, but we can probably agree that in this space, this is great news. The only thing to keep in mind is that it's still in "Early Preview" stage, so I wouldn't recommend relying on Astro DB for critical production workloads. &lt;/p&gt;

&lt;p&gt;Anyway, as soon as I saw the announcement, I jumped right in and tried to implement a feature for my blog: a basic page views counter. How hard could it be? &lt;/p&gt;

&lt;h2&gt;
  
  
  Page views counter
&lt;/h2&gt;

&lt;p&gt;I admit, it's not a very creative idea. My goal was to explore Astro DB, see how it works, so that I can actually use it for something fun later. So, page views counter it is. &lt;/p&gt;

&lt;p&gt;The plan was simple: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Whenever somebody visits any page on my website, I'd record their visit in the database&lt;/li&gt;
&lt;li&gt;To make this counter a little more resilient, I'd also record hashed user IP address and their hashed user agent (I don't want to collect or store &lt;em&gt;actual&lt;/em&gt; IPs and user agents, but I do want to be able to identify whether somebody is just hitting refresh or actually visiting a page)&lt;/li&gt;
&lt;li&gt;I also need to record that page is being visited&lt;/li&gt;
&lt;li&gt;I want to display the view counts per page&lt;/li&gt;
&lt;li&gt;Finally, I want to display popular blog posts based on the number of page views&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Multiple improvements to this basic approach can be made. But for my exploration purpose, this is quite enough.&lt;/p&gt;

&lt;h3&gt;
  
  
  Configuration
&lt;/h3&gt;

&lt;p&gt;First things first. I'd need to install, enable, and configure @astrojs/db. There are different ways to install Astro integrations, and I usually prefer the automated one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm astro add db
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command installs the package, updates &lt;code&gt;astro.config.mjs&lt;/code&gt;, and creates a new directory called &lt;code&gt;db&lt;/code&gt; with &lt;code&gt;config.ts&lt;/code&gt; and &lt;code&gt;seed.ts&lt;/code&gt; files in it. That's about it. The project is ready, let's dive in.&lt;/p&gt;

&lt;p&gt;Here's what my &lt;code&gt;config.ts&lt;/code&gt; looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;defineDb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;defineTable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;column&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;astro:db&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Visits&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;defineTable&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;column&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;number&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;primaryKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="na"&gt;page&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;column&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;home&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;column&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="na"&gt;pagination&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;column&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;number&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="na"&gt;visitor_ip_hash&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;column&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="na"&gt;visitor_user_agent_hash&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;column&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="na"&gt;visitor_count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;column&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;number&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&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;span class="c1"&gt;// https://astro.build/db/config&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;defineDb&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;tables&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Visits&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;Pretty self-explanatory: we import &lt;code&gt;defineDb&lt;/code&gt; from &lt;code&gt;astro:db&lt;/code&gt; so that we can define our database, &lt;code&gt;defineTable&lt;/code&gt; so that we can define this database's tables, and &lt;code&gt;column&lt;/code&gt;, you guessed it, so that we can define this table's columns. There's more we can do, but for now that's all we need.&lt;/p&gt;

&lt;p&gt;Now, if you've ever worked with a local database, you know you now need to actually start the local database, create tables, and seed it. Well, with Astro DB, you only need to do the last step - seed the db. And &lt;em&gt;need&lt;/em&gt; is really &lt;em&gt;want&lt;/em&gt;: you're not &lt;em&gt;required&lt;/em&gt; to seed the database, it just makes life easier down the line.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Visits&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;astro:db&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// https://astro.build/db/seed&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;seed&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Visits&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;values&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;page&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;home&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;pagination&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;visitor_ip_hash&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;30963a87dd481e4366237ed9cb37f001e24bcb865833be0036f7f081176b9812&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;visitor_user_agent_hash&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;c08ae1ccbe7296f4d6589acb026c5a0379bb07f1915cca8829d4cead13211e26&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;visitor_count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&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 file will create a record in the local database (you &lt;em&gt;can&lt;/em&gt; seed remote database as well!); whenever you restart your development server (&lt;code&gt;astro dev&lt;/code&gt;), the database gets reset and re-seeded. How cool is that?!&lt;/p&gt;

&lt;p&gt;What's important here is that you now have access to &lt;code&gt;Visits&lt;/code&gt; and &lt;code&gt;db&lt;/code&gt; anywhere in your project, and can just use them right away!&lt;/p&gt;

&lt;h3&gt;
  
  
  Accessing Astro Studio
&lt;/h3&gt;

&lt;p&gt;Before moving forward with the views counter implementation, let me quickly note a few things about local and remote databases. &lt;/p&gt;

&lt;p&gt;When you develop locally, the database is reset every time you restart the development server. &lt;/p&gt;

&lt;p&gt;When you're happy with the schema, you can push this schema to the remote database, the one that's going to be used when you deploy your project. The CLI is pretty straightforward here: you login to Astro Studio, link your local database to a (new) project, push local changes to this remote DB.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;astro db login &lt;span class="c"&gt;# Follow prompts, login with Github&lt;/span&gt;

astro db &lt;span class="nb"&gt;link&lt;/span&gt; &lt;span class="c"&gt;# Again, follow prompts, create a new project or link local db to an existing one&lt;/span&gt;

astro db push &lt;span class="c"&gt;# Tell the remote DB what you want it to look like&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As an added feature, you could also seed the remote database:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;astro db execute db/seed.ts &lt;span class="nt"&gt;--remote&lt;/span&gt; &lt;span class="c"&gt;# "db/seed.ts" here is just a path to the file where your seed data is. &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Oh, and you &lt;em&gt;can&lt;/em&gt; use the remote database locally! Just be &lt;em&gt;very&lt;/em&gt; careful.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;astro dev &lt;span class="nt"&gt;--remote&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, go to &lt;a href="https://studio.astro.build/"&gt;Astro Studio&lt;/a&gt;, log in, and click around. You'll see your new project and its database. Notice, that I have &lt;code&gt;SQL Console&lt;/code&gt; enabled: if you need to just run a few SQL commands, it's a nice thing to have.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fczddcvi7wqymc8466mjj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fczddcvi7wqymc8466mjj.png" alt="Astro Studio UI" width="800" height="397"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, Astro Studio is pretty limited in what you can see and do there, but it does cover all the bases and again, it's an "Early Preview". What I use Studio the most for is inspecting records, and it does a pretty good job here.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh3dnnc08lcqhzrop5aal.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh3dnnc08lcqhzrop5aal.png" alt="Astro Studio database UI" width="800" height="379"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Implementation
&lt;/h3&gt;

&lt;p&gt;Aaaanyway, after I got my Astro DB all set up, I got to the actual implementation of the page views counter. I don't want to bore you with the details that are &lt;em&gt;very&lt;/em&gt; specific to my particular website, so I'd boil it down to more generic steps.&lt;/p&gt;

&lt;p&gt;The first step is to figure out how we are going to register visits. There are multiple ways to approach this depending on what Astro &lt;a href="https://docs.astro.build/en/basics/rendering-modes/"&gt;rendering &lt;code&gt;mode&lt;/code&gt;&lt;/a&gt; you're using: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;in &lt;code&gt;static&lt;/code&gt; or &lt;code&gt;hybrid&lt;/code&gt; mode, you could load a counter &lt;code&gt;pixel&lt;/code&gt; (a 1x1 pixel image pointing to an &lt;a href="https://docs.astro.build/en/guides/endpoints/"&gt;endpoint&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;in &lt;code&gt;server&lt;/code&gt; or &lt;code&gt;hybrid&lt;/code&gt; mode with &lt;code&gt;export const prerender = false&lt;/code&gt;, you could make a call directly to the endpoint that counts visits&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;My website is primarily static; I use &lt;code&gt;hybrid&lt;/code&gt; mode so that I do have an option to disable prerendering when I need to. It actually poses some quite specific challenges that I won't go into here, but just keep this in mind: if something doesn't work the way you expect it to work, check your rendering mode first :)&lt;/p&gt;

&lt;p&gt;I've added my &lt;code&gt;pixel&lt;/code&gt; to the footer of my site along with a &lt;code&gt;Views&lt;/code&gt; component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Footer.astro&lt;/span&gt;
&lt;span class="o"&gt;---&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;currentPage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Astro&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="nx"&gt;pathname&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// naive "give me the current page url" kind of thing&lt;/span&gt;
&lt;span class="nx"&gt;currentPage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;shift&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// oh, and remove the leading `/` &lt;/span&gt;
&lt;span class="o"&gt;---&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Image&lt;/span&gt; 
  &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`/visitors/register?page=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;currentPage&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; 
  &lt;span class="na"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"eager"&lt;/span&gt; 
  &lt;span class="na"&gt;aria-hidden&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt; 
  &lt;span class="na"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"tracking pixel"&lt;/span&gt; 
  &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt; 
  &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Views&lt;/span&gt; &lt;span class="na"&gt;client&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="na"&gt;only&lt;/span&gt; &lt;span class="na"&gt;currentPage&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;currentPage&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, I just need to actually register visits. That's where the magic happens!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/pages/visitors/register.ts&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;prerender&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;crypto&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;node:crypto&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Visits&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;and&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;astro:db&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;APIRoute&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;astro&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;GET&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;APIRoute&lt;/span&gt; &lt;span class="o"&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;data&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="nx"&gt;hash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createHash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sha256&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;digest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hex&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="na"&gt;userAgent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;User-Agent&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="na"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clientAddress&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="na"&gt;pagePathName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;request&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="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pagePaths&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;pagePathName&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;pagePathName&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;,&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;span class="p"&gt;[];&lt;/span&gt;

  &lt;span class="c1"&gt;// This is lazy and dumb, ignore it&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;home&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;pagination&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pagePathName&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;page&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;home&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pagePaths&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&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="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;page&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;pagePaths&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pagePaths&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&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="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;page&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;pagePaths&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nx"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;pagePaths&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pagePaths&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;page&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;pagePaths&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nx"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;pagePaths&lt;/span&gt;&lt;span class="p"&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;pagination&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pagePaths&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="p"&gt;}&lt;/span&gt;
  &lt;span class="c1"&gt;// The end of "this is lazy and dumb, ignore it"&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;userAgentHash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userAgent&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ipHash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ip&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;visits&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;db&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Visits&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nf"&gt;and&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nf"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Visits&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;visitor_ip_hash&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ipHash&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; 
        &lt;span class="nf"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Visits&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;visitor_user_agent_hash&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;userAgentHash&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; 
        &lt;span class="nf"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Visits&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; 
        &lt;span class="nf"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Visits&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; 
        &lt;span class="nf"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Visits&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pagination&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pagination&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;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;visits&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Visits&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; 
        &lt;span class="na"&gt;visitor_count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;visits&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;visitor_count&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="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nf"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Visits&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;visits&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="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Visits&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;values&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;pagination&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;visitor_ip_hash&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ipHash&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;visitor_user_agent_hash&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;userAgentHash&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;visits&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&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;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;application/json&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;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I first check if a visit from this particular visitor to this specific page has been registered already, and if so, I increase the count (I should also be checking for a timestamp here, come to think of it). If it's a brand new visit, I do &lt;code&gt;db.insert&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Now, how do we display the number of view? Here's what my &lt;code&gt;Views.tsx&lt;/code&gt; looks like. NB: I'd very much prefer for this "dynamic" component to be an Astro component, alas it has to be (p)react (I'm using the official &lt;a href="https://docs.astro.build/en/guides/integrations-guide/preact/"&gt;preact integration&lt;/a&gt;).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Views.tsx&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Suspense&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;lazy&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;preact/compat&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ViewsCount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;lazy&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./ViewsCount&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; 

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Views&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;currentPage&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;currentPage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&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="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Suspense&lt;/span&gt; &lt;span class="na"&gt;fallback&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Loading Views...&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ViewsCount&lt;/span&gt; &lt;span class="na"&gt;currentPage&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;currentPage&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Suspense&lt;/span&gt;&lt;span class="p"&gt;&amp;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;And the actual counter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ViewsCount.tsx&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;preact/hooks&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ViewsCount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;currentPage&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;currentPage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;}):&lt;/span&gt; &lt;span class="nx"&gt;JSX&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Element&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;views&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setViews&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

  &lt;span class="nf"&gt;useEffect&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="nx"&gt;fetchViews&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &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="nx"&gt;visitsData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`/visitors/count?&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;currentPage&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;visits&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;visitsData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

      &lt;span class="nf"&gt;setViews&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;visits&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;fetchViews&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;span class="nx"&gt;currentPage&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"mt-8 text-base text-slate-400/90 md:mt-0"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Views: &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;views&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;ViewsCount&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The combination of these two components results in a "Loading Views..." text while the view counter is fetching it's number from the DB, and the number of views when it's ready:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjal1y5u3l824e9zuqs62.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjal1y5u3l824e9zuqs62.png" alt="Views counter" width="800" height="59"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, how is the count number gets returned from the database?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/pages/visitors/count.ts&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Visits&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;and&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;astro:db&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;APIRoute&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;astro&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;prerender&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;GET&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;APIRoute&lt;/span&gt; &lt;span class="o"&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;data&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="nx"&gt;currentPage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;request&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="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;?&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;,&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;visitsData&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;db&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Visits&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nf"&gt;and&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="c1"&gt;// this is the part where some wierd specifics of my site come into play&lt;/span&gt;
        &lt;span class="nf"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Visits&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;currentPage&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;===&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;home&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;currentPage&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt; 
        &lt;span class="nf"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Visits&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;currentPage&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;currentPage&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;none&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;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;visits&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;visitsData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;item&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;acc&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;visitor_count&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;visits&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&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;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;application/json&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;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And there you have it. But we are not done yet!&lt;/p&gt;

&lt;h3&gt;
  
  
  Popular posts
&lt;/h3&gt;

&lt;p&gt;With all this in place, I can now display not only latest posts but also most popular (by views). Note that I make sure to remove the three latest posts that are already featured on the page so that I don't get identical posts in Latest and Popular sections.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="o"&gt;---&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Container&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@components/Container.astro&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;BlogGrid&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@components/blog/BlogGrid.astro&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Underline&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@components/illustrations/Underline.astro&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Visits&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ne&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;and&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;desc&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;astro:db&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getSortedPosts&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@utils/posts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Post&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@types&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getCollection&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;astro:content&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;featuredPosts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getSortedPosts&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;popularPostsByVisits&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Visits&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nf"&gt;ne&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Visits&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;none&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;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;orderBy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nf"&gt;desc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Visits&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;visitor_count&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;rows&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;rows&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;row&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;row&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&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;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;featuredPostsSlugs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;featuredPosts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;pop&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;popularPostsSlugs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;popularPostsByVisits&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;featuredPostsSlugs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;allPosts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Post&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="nf"&gt;getSortedPosts&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;popularPosts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;allPosts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;popularPostsSlugs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;pop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="o"&gt;---&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;section&lt;/span&gt;
  &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"overflow-hidden bg-white py-16 dark:bg-slate-900 sm:pt-24 lg:pt-28"&lt;/span&gt;
&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Container&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Popular Posts&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;BlogGrid&lt;/span&gt; &lt;span class="na"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;popularPosts&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Container&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;section&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  All done!
&lt;/h2&gt;

&lt;p&gt;Well, now we are done. Setting up Astro DB was easy, it's easy to use, and it works as expected. I bet there are some awesome improvements coming, but in the meantime, Astro DB is my go-to for all my Astro-based projects.&lt;/p&gt;

&lt;p&gt;How would you use Astro DB? Any cool ideas? :)&lt;/p&gt;

</description>
      <category>astro</category>
      <category>ssr</category>
      <category>astrodb</category>
      <category>astrostudio</category>
    </item>
    <item>
      <title>Do you want to build a service?</title>
      <dc:creator>Art Rosnovsky</dc:creator>
      <pubDate>Sat, 01 Feb 2020 23:28:12 +0000</pubDate>
      <link>https://dev.to/rosnovsky/do-you-want-to-build-a-service-27bd</link>
      <guid>https://dev.to/rosnovsky/do-you-want-to-build-a-service-27bd</guid>
      <description>&lt;p&gt;It’s Saturday, and I’m at work. I worked last Saturday as well, and will be working tomorrow too. I do this 100% voluntarily, because believe it or not, I enjoy &lt;a href="https://rosnovsky.us/blog/2019/12/26/new-job/"&gt;my new job&lt;/a&gt;. I don’t have to be here, I don’t have to come to the office every day or even most days, but I do nonetheless. Because I like it, it brings me joy, I have fun, I learn, my team is awesome, and I get free granola and coffee :)&lt;/p&gt;

&lt;p&gt;However, I’m old enough to realize that this sort of pace is not sustainable long-term. People get burnt out at the most fantastic dream jobs; their families suffer, friendships fall apart, even while their careers soar and they enjoy every moment of their work life. We all need breaks, even from the most fulfilling activities.&lt;/p&gt;

&lt;p&gt;So… Breaks, huh? Something to take your mind off work, daily tasks, goals, OKRs, KPIs, or what have you. People do all sorts of different things: they hike, they travel, read books at their favorite coffee shops, hang out with friends, watch TV, eat out, draw, make podcasts, brew beer, learn pottery or how to fly an airplane. The list is endless, and most people find something enjoyable to do besides work. &lt;/p&gt;

&lt;p&gt;I’d most definitely go on an overnight solo hike this summer. I will absolutely fly a helicopter this summer at least once. It’s very likely that I’m going to visit friends in Portland in late July or August. I have a list of books I want to read, and I most certainly will.&lt;/p&gt;

&lt;p&gt;As fun as they are, these activities are not of the “all-consuming” kind. They are a bunch of events, not a continuous process. Even though you could fill your life with these activities, they are fleeting. That’s why I’m embarking on this project I want to talk about.&lt;/p&gt;

&lt;p&gt;You may or may not have heard about &lt;a href="//750words.com"&gt;750words.com&lt;/a&gt;. It’s a service that allows you to type 750 words a day. Any words, just let your thoughts flow. I loved it in the past, and still thinks its therapeutic value cannot be overestimated. Unfortunately, it hasn’t been updating recently, and I thought what if I make my own service of this kind? Hear me out.&lt;/p&gt;

&lt;p&gt;I want to build a service where I can vent, rant or just let my thoughts flow freely. I want this service to help me understand where I am, how I actually feel, and be an outlet for my emotions. I also want this service to be an educational project, that would occupy me outside my work and provide new skills, entertainment and something exciting to do.&lt;/p&gt;

&lt;p&gt;The app I will be building will be focused around mental health, healthy coping mechanisms, gratitude, and self care. To make it more fun, it will have all sorts of stats, graphs and charts, sentiment analysis, badges and more. I’m still defining requirements, so it’s all fluid.&lt;/p&gt;

&lt;p&gt;In a nutshell, I’ll be building a note-taking web application (React or Svelte) powered by serverless functions and a cloud database and GraphQL. Notes will be encrypted at rest, and there will be a machine learning component for sentiment analysis. I’ve got a bunch of extra point ideas (AI generated background music for file you type your notes, live stats, voice notes made with a mobile app automatically transcribed, and so on).&lt;/p&gt;

&lt;p&gt;I know very little about technologies this project involves. I mean, I’ve done at least a “hello world” in all of them, but I don’t know enough to just sit down and build this all. So my objectives for this project are in no particular order:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Learn the tech&lt;/li&gt;
&lt;li&gt;Get my mind off work for an interesting project&lt;/li&gt;
&lt;li&gt;Build an app from zero to hero&lt;/li&gt;
&lt;li&gt;Get a service I’d like to use&lt;/li&gt;
&lt;li&gt;Hopefully, involve other people and grow together with them&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At this time, I’ve only set up a &lt;a href="https://github.com/rosnovsky/pinetype"&gt;repository&lt;/a&gt; and filling its project section. So it’s very early, and if you’re looking for something fun to learn in 2020, chime in and let’s do it together. There’s absolutely no pressure behind this project, no monetization concerns, no marketing or building a user base. Just learning, building, exploring, and a helpful service at the end. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/rosnovsky/pinetype"&gt;Hit me up on Github&lt;/a&gt; if you think it’s something you’d like to be a part of. All skills are welcome (from design to devops), all levels are welcome (from total newbies to enlightened seniors). &lt;strong&gt;I guarantee 100% inclusive, safe and friendly learning and building environment.&lt;/strong&gt; Join me!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>serverless</category>
      <category>learning</category>
    </item>
    <item>
      <title>30 Best Dev and Tech Podcasts</title>
      <dc:creator>Art Rosnovsky</dc:creator>
      <pubDate>Wed, 17 Jul 2019 03:36:14 +0000</pubDate>
      <link>https://dev.to/rosnovsky/30-best-dev-and-tech-podcasts-35dh</link>
      <guid>https://dev.to/rosnovsky/30-best-dev-and-tech-podcasts-35dh</guid>
      <description>&lt;p&gt;It's hard to believe, but I've been listening to podcasts for almost 15 years, and been podcasting myself since April 2006. Just think about it: back then Youtube had just pivoted from being &lt;a href="https://www.cnet.com/news/youtube-started-as-an-online-dating-site/" rel="noopener noreferrer"&gt;a dating site&lt;/a&gt;, Twitter had like 150 active users, Uber won't exist for another 3 years or so, and the most innovative mobile phone companies in the world are Nokia and Blackberry. Blockbuster was huge, and Lost was the biggest TV show of all time, still in Season 3 :)&lt;/p&gt;

&lt;p&gt;Podcasting never took off the way video streaming did, but I don't think it's an issue. Spoken word historically loses to moving pictures in popularity, but more often then not wins in substance and depth. Not only this, but podcasts do not require the same level of focus and concentration as does, say, Youtube. You can't really drive and watch &lt;a href="https://www.youtube.com/user/Kurzgesagt" rel="noopener noreferrer"&gt;Kurzgesagt&lt;/a&gt;, but you can drive and listen to &lt;a href="https://gimletmedia.com/shows/science-vs" rel="noopener noreferrer"&gt;Science Vs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here's a list of my favorite podcasts. Some of them are in their second decade of running, some are pretty new, but all of them are a tremendous source of knowledge, news, and human experience as it relates to hitech industry in general, and software development in particular. Feel free to make a &lt;a href="https://github.com/rosnovsky/rosnovskyus/blob/master/src/content/blog/tech-podcasts-in-2019.md" rel="noopener noreferrer"&gt;pull request&lt;/a&gt; if you think I've missed a great show here!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt; You can &lt;a href="https://github.com/rosnovsky/rosnovskyus/blob/master/src/content/blog/30-top-tech-podcasts-in-2019/overcast.opml" rel="noopener noreferrer"&gt;download a complete OPML list of all 30 shows&lt;/a&gt; mentioned below. Just feed it to your favorite podcast app (I suggest &lt;a href="https://overcast.fm/" rel="noopener noreferrer"&gt;Overcast&lt;/a&gt;) and have all these shows in you subscriptions right away!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Dev
&lt;/h2&gt;

&lt;p&gt;Dev podcasts provide a great deal of information and an amazing learning experience. They also give a greater sense of community and feeling of belonging. Below is a list of podcasts that deal directly with software and web development.  &lt;/p&gt;

&lt;h3&gt;
  
  
  1. &lt;a href="https://syntax.fm/" rel="noopener noreferrer"&gt;Syntax&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Relatively new and a real hit. Two hosts, Wes "Barracuda" Bos &amp;amp; Scott "El Toro Loco" Tolinski, normally make JavaScript courses and speak at conferences, but every now and then (more like a few times a week) they get together and talk shop. From general things like how do you advance as a freelancer or get your first dev job to the newest CSS tricks and &lt;em&gt;sick&lt;/em&gt; latest internalization features. "Potluck" Q&amp;amp;A episodes and on-point "Tasty Treats".&lt;/p&gt;

&lt;p&gt;&lt;small&gt;Syntax &lt;a href="https://itunes.apple.com/ca/podcast/syntax-tasty-web-development-treats/id1253186678?mt=2" rel="noopener noreferrer"&gt;iTunes&lt;/a&gt; | Syntax &lt;a href="http://feed.syntax.fm/rss" rel="noopener noreferrer"&gt;RSS&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  2. &lt;a href="https://reactpodcast.simplecast.fm/" rel="noopener noreferrer"&gt;React Podcast&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;It's all in the name. From interviews with core React team members to vision and in-depth specifics of the framework we all love (and &lt;a href="https://2018.stateofjs.com/front-end-frameworks/overview/" rel="noopener noreferrer"&gt;we do love it&lt;/a&gt;!) to career discussions.&lt;/p&gt;

&lt;p&gt;&lt;small&gt;React Podcast &lt;a href="https://podcasts.apple.com/us/podcast/the-react-podcast/id1341969432" rel="noopener noreferrer"&gt;iTunes&lt;/a&gt; | React Podcast &lt;a href="https://rss.simplecast.com/podcasts/6265/rss" rel="noopener noreferrer"&gt;RSS&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  3. &lt;a href="https://softwareengineeringdaily.com/" rel="noopener noreferrer"&gt;Software Engineering Daily&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;A broad look on basically all things software dev. This one is not specific to web development, though. To be honest, I don't have &lt;em&gt;that&lt;/em&gt; much time, and I do have a lot of other good podcasts to listen to, so personally, I skim shownotes of new episodes and listen to those that look promising. Interesting topics come up more often then not, but time is a finite resource, unfortunately.&lt;/p&gt;

&lt;p&gt;&lt;small&gt;Software Engineering Daily &lt;a href="https://podcasts.apple.com/us/podcast/software-engineering-daily/id1019576853?ls=1&amp;amp;mt=2" rel="noopener noreferrer"&gt;iTunes&lt;/a&gt; | Software Engineering Daily &lt;a href="https://softwareengineeringdaily.com/category/podcast/feed" rel="noopener noreferrer"&gt;RSS&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  4. &lt;a href="https://changelog.com/podcast" rel="noopener noreferrer"&gt;The Changelog&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;The Changelog has been around for quite some time now. Episodes feature prominent engineers, developers, and other experts, and usually have a specific topic.&lt;/p&gt;

&lt;p&gt;&lt;small&gt;The Changelog &lt;a href="https://itunes.apple.com/us/podcast/the-changelog/id341623264" rel="noopener noreferrer"&gt;iTunes&lt;/a&gt; | The Changelog &lt;a href="https://changelog.com/podcast/feed" rel="noopener noreferrer"&gt;RSS&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  5. &lt;a href="https://changelog.com/jsparty" rel="noopener noreferrer"&gt;JS Party&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;🎉🎉🎉&lt;br&gt;
Fun and casual, the kind of chat you'd like to be a part of. As serious as some topics are (burnout, anyone?), episodes are mostly on the inspiring and empowering side.  &lt;/p&gt;

&lt;p&gt;&lt;small&gt;JS Party &lt;a href="https://itunes.apple.com/us/podcast/js-party/id1209616598" rel="noopener noreferrer"&gt;iTunes&lt;/a&gt; | JS Party &lt;a href="https://changelog.com/jsparty/feed" rel="noopener noreferrer"&gt;RSS&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  6. &lt;a href="https://spec.fm/podcasts/developer-tea" rel="noopener noreferrer"&gt;Developer Tea&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Developer Tea is on a shorter, bite-size side of podcasting. Inspiring and useful to both newbies and seasoned developers, and available to anyone with a 20+ minute commute. I even trained my Alexa to give me new Developer Tea in the morning, and most days their episodes fit nicely into my breakfast routine.   &lt;/p&gt;

&lt;p&gt;&lt;small&gt;Developer Tea &lt;a href="https://geo.itunes.apple.com/ca/podcast/feed/id955596067" rel="noopener noreferrer"&gt;iTunes&lt;/a&gt; | Developer Tea &lt;a href="http://feeds.feedburner.com/developertea" rel="noopener noreferrer"&gt;RSS&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  7. &lt;a href="http://www.fullstackradio.com/" rel="noopener noreferrer"&gt;Full Stack Radio&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Weekly in-depth interview show with Adam Wathan. Sometimes I listen to the guests and wonder if I'd ever have such an enormous and complete understanding of tech as they do. &lt;/p&gt;

&lt;p&gt;&lt;small&gt;Full Stack Radio &lt;a href="https://geo.itunes.apple.com/ca/podcast/feed/id955596067" rel="noopener noreferrer"&gt;iTunes&lt;/a&gt; | Full Stack Radio &lt;a href="https://rss.simplecast.com/podcasts/279/rss" rel="noopener noreferrer"&gt;RSS&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  8. &lt;a href="https://shoptalkshow.com/" rel="noopener noreferrer"&gt;Shop Talk&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Another great show about front end development, web design and all things UX. It's interesting how sometimes you hear same guests on different podcasts from this list, but every host and every show has a different angle and offers a different conversation. Exciting guests, great in-depth talks.  &lt;/p&gt;

&lt;p&gt;&lt;small&gt;Shop Talk &lt;a href="http://itunes.apple.com/podcast/id493890455" rel="noopener noreferrer"&gt;iTunes&lt;/a&gt; | Shop Talk &lt;a href="https://shoptalkshow.com/feed/podcast" rel="noopener noreferrer"&gt;RSS&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  9. &lt;a href="https://freecodecamp.libsyn.com/" rel="noopener noreferrer"&gt;FreeCodeCamp&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://freecodecamp.org" rel="noopener noreferrer"&gt;FreeCodeCamp&lt;/a&gt; is one of the absolutely best and completely free and open-source resources for learning software development. It's been growing like crazy, has incredible community of passionate people who are happy to share their knowledge and help out the newbies. Their podcast is no exception: awesome guests, stimulating topics, success stories and so much more. Highly recommended!&lt;/p&gt;

&lt;p&gt;&lt;small&gt;FreeCodeCamp &lt;a href="https://itunes.apple.com/us/podcast/the-freecodecamp-podcast/id1313660749?mt=2&amp;amp;ls=1" rel="noopener noreferrer"&gt;iTunes&lt;/a&gt; | FreeCodeCamp &lt;a href="http://podcast.freecodecamp.org/rss" rel="noopener noreferrer"&gt;RSS&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  10. &lt;a href="https://secondcareerdevs.com/" rel="noopener noreferrer"&gt;Second Career Devs&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Kyle talks with people who became software engineers after they had a previous career in other fields. This one is particularly dear to me since I've been a journalist and a radio host in my &lt;em&gt;previous life&lt;/em&gt;, and can very much relate being a second career developer myself. &lt;/p&gt;

&lt;p&gt;&lt;small&gt;Second Career Devs &lt;a href="https://podcasts.apple.com/us/podcast/second-career-devs/id1317467797" rel="noopener noreferrer"&gt;iTunes&lt;/a&gt; | Second Career Devs &lt;a href="http://feeds.soundcloud.com/users/soundcloud:users:332558027/sounds.rss" rel="noopener noreferrer"&gt;RSS&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  11. &lt;a href="https://maintainable.fm/" rel="noopener noreferrer"&gt;Maintainable&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Legacy code, technical debt, and how to maintain and advance older projects (personal or at work). This one is tailored more towards seasoned developers audience, but anyone could benefit regardless of current experience level.&lt;/p&gt;

&lt;p&gt;&lt;small&gt;Maintainable &lt;a href="https://podcasts.apple.com/us/podcast/maintainable/id1459893010" rel="noopener noreferrer"&gt;iTunes&lt;/a&gt; | Maintainable &lt;a href="https://feeds.simplecast.com/7y1CbAbN" rel="noopener noreferrer"&gt;RSS&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  12. &lt;a href="https://blog.codepen.io/radio/" rel="noopener noreferrer"&gt;CodePen Radio&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;CodePen is an awesome tool for quickly prototyping a feature, showcasing some code, doing an exercise or collaborating on a project. They run an insightful podcast about, well, running a web software business.  &lt;/p&gt;

&lt;p&gt;&lt;small&gt;CodePen Radio &lt;a href="https://itunes.apple.com/us/podcast/codepen-radio/id824437159" rel="noopener noreferrer"&gt;iTunes&lt;/a&gt; | CodePen Radio &lt;a href="https://blog.codepen.io/feed/podcast/" rel="noopener noreferrer"&gt;RSS&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  13. &lt;a href="https://www.codingblocks.net/" rel="noopener noreferrer"&gt;Coding Blocks&lt;/a&gt;
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Podcast about computer programming and software development so you can learn on the go. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Indeed. Topics vary greatly, but you'll find yourself diving deep into different programming concepts and learning a whole lot of new stuff every month.&lt;/p&gt;

&lt;p&gt;&lt;small&gt;Coding Blocks &lt;a href="https://podcasts.apple.com/podcast/coding-blocks-software-web/id769189585" rel="noopener noreferrer"&gt;iTunes&lt;/a&gt; | Coding Blocks &lt;a href="https://www.codingblocks.net/podcast-feed.xml" rel="noopener noreferrer"&gt;RSS&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  General Tech Talk
&lt;/h2&gt;

&lt;p&gt;More on the general side, these podcasts cover tech news. Some of them go in-depth with philosophical implications of tech stories, some deal with particulars of working in tech.&lt;/p&gt;

&lt;h3&gt;
  
  
  14. &lt;a href="https://www.twit.tv/shows/this-week-in-tech" rel="noopener noreferrer"&gt;This Week in Tech&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Leo Laporte is a true legend and one of the pioneers of podcasting. His &lt;a href="https://www.twit.tv/" rel="noopener noreferrer"&gt;TWiT&lt;/a&gt; network runs a whole bunch of shows, from Cyber Security to iOS to daily tech news. I consider This Week in Tech to be the weekly tech news podcast.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4fbvbs29f67326yht8e9.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4fbvbs29f67326yht8e9.jpg" alt="Leo Laporte" width="800" height="452"&gt;&lt;/a&gt;&lt;br&gt;
P.S. I've met with Leo once a while back, it was fun :)&lt;/p&gt;

&lt;p&gt;&lt;small&gt;This Week in Tech &lt;a href="https://podcasts.apple.com/us/podcast/this-week-in-tech-mp3/id73329404?uo=10" rel="noopener noreferrer"&gt;iTunes&lt;/a&gt; | This Week in Tech &lt;a href="http://feeds.twit.tv/twit.xml" rel="noopener noreferrer"&gt;RSS&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  15. &lt;a href="https://atp.fm/" rel="noopener noreferrer"&gt;Accidental Tech Podcast&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Marco Arment, Casey Liss, and John Siracusa, a trio of well-known software developers, writers and producers, run this very special show. It's both sarcastic, and optimistic, and all-doom-and-gloom at times, but then it's something else completely. It's all over the place in the best sense possible. It is quite heavily Apple-leaning, since hosts been covering Apple or working with Apple stack for decades. Marco Arment, for instance, is the person responsible for &lt;a href="https://overcast.fm/" rel="noopener noreferrer"&gt;Overcast&lt;/a&gt;, without a doubt the best podcast app out there. &lt;/p&gt;

&lt;p&gt;&lt;small&gt;Accidental &lt;a href="https://itunes.apple.com/us/podcast/accidental-tech-podcast/id617416468" rel="noopener noreferrer"&gt;iTunes&lt;/a&gt; | Accidental &lt;a href="http://atp.fm/episodes?format=rss" rel="noopener noreferrer"&gt;RSS&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  16. &lt;a href="https://www.indiehackers.com/podcast" rel="noopener noreferrer"&gt;Indie Hackers&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;I couldn't skip Indie Hackers, although this is probably one of the podcasts that I'm not entirely sure I like :) Sometimes it's a lot of hype, and guests are this self-made kind of know-it-alls, but then they strike gold with a meaningful, inspiring, and overall great conversation with someone who's humble because they &lt;em&gt;truly&lt;/em&gt; know their stuff. Hit and miss, in short, but still worth a sub.&lt;/p&gt;

&lt;p&gt;&lt;small&gt;Indie Hackers &lt;a href="//itms://itunes.apple.com/us/podcast/indie-hackers-podcast-how/id1206165808"&gt;iTunes&lt;/a&gt; | Indie Hackers &lt;a href="https://feeds.backtracks.fm/indiehackers/indie-hackers-podcast/feed.xml" rel="noopener noreferrer"&gt;RSS&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Apple &amp;amp; Mac
&lt;/h2&gt;

&lt;p&gt;As we all know, Apple &lt;em&gt;invented&lt;/em&gt; podcasts. To exactly no one's surprise, Apple is heavily covered by dozens of different shows. The company is beloved by some, and despised by others, but I really don't know a single person who's completely indifferent towards Apple. &lt;/p&gt;

&lt;h3&gt;
  
  
  17. &lt;a href="https://www.twit.tv/shows/macbreak-weekly" rel="noopener noreferrer"&gt;MacBreak Weekly&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;This is the oldest Mac and Apple show in existence; I remember watching one of the first ever HD videos I've ever watched, like, 50 years ago or something, and this first video was one of the how-to episodes of MBW (I still remember the opening score along with the video, and how long it took to download, and how very jittery it was on my old computer). One of my all-time favorites.&lt;/p&gt;

&lt;p&gt;&lt;small&gt;MacBreak Weekly &lt;a href="https://podcasts.apple.com/us/podcast/macbreak-weekly-mp3/id179237749?uo=10" rel="noopener noreferrer"&gt;iTunes&lt;/a&gt; | MacBreak Weekly &lt;a href="http://feeds.twit.tv/mbw.xml" rel="noopener noreferrer"&gt;RSS&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  18. &lt;a href="https://www.relay.fm/upgrade" rel="noopener noreferrer"&gt;Upgrade&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Co-founder of Relay.fm network Myke Hurley and his legendary co-host Jason Snell, in a heavily Apple leaning show about tech. They tend to look at all the tech scene through &lt;em&gt;Apple glasses&lt;/em&gt;, and they do a great job spinning Apple stuff.&lt;/p&gt;

&lt;p&gt;&lt;small&gt;Upgrade &lt;a href="https://itunes.apple.com/us/podcast/upgrade/id918152703" rel="noopener noreferrer"&gt;iTunes&lt;/a&gt; | Upgrade &lt;a href="https://overcast.fm/itunes918152703/upgrade" rel="noopener noreferrer"&gt;RSS&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  19. &lt;a href="https://www.imore.com/vector" rel="noopener noreferrer"&gt;Vector&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Rene Ritchie of iMore runs this (almost) daily (and sometimes twice-a-day) show about personal tech in general and Apple tech in particular. Rene is great at explaining things, and usually he gets to the bottom of whatever he's talking about before actually talking about it. &lt;/p&gt;

&lt;p&gt;&lt;small&gt;Vector &lt;a href="http://applepodcasts.com/vector" rel="noopener noreferrer"&gt;iTunes&lt;/a&gt; | Vector &lt;a href="http://vector.libsyn.com/rss" rel="noopener noreferrer"&gt;RSS&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  20. &lt;a href="https://www.relay.fm/connected" rel="noopener noreferrer"&gt;Connected&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;A unique mix of perspectives and accents. Apple-focused, this show offers a great deal of commentary and opinions you might disagree with. Just saying :)&lt;/p&gt;

&lt;p&gt;&lt;small&gt;Connected &lt;a href="https://itunes.apple.com/us/podcast/id909109652" rel="noopener noreferrer"&gt;iTunes&lt;/a&gt; | Connected &lt;a href="https://overcast.fm/itunes909109652/connected" rel="noopener noreferrer"&gt;RSS&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Google &amp;amp; Android
&lt;/h2&gt;

&lt;p&gt;Googleverse is of course a thing, and quite a few exciting things go on in this universe at any given moment. &lt;/p&gt;

&lt;h3&gt;
  
  
  21. &lt;a href="https://www.twit.tv/shows/this-week-in-google" rel="noopener noreferrer"&gt;This Week in Google&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;This actually is quite a show. It is called This Week in Google, but man, do they ever stick to the topic! I mean it as a compliment, really: tha show is broader then just Google news, and covers everything even remotely related to Google, or Google's tech, or Google's potential tech, or future of technology, or whatever is exciting today :)&lt;/p&gt;

&lt;p&gt;&lt;small&gt;This Week in Google &lt;a href="https://podcasts.apple.com/us/podcast/this-week-in-google-mp3/id326120877?uo=10" rel="noopener noreferrer"&gt;iTunes&lt;/a&gt; | This Week in Google &lt;a href="http://feeds.twit.tv/twig.xml" rel="noopener noreferrer"&gt;RSS&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  22. &lt;a href="https://www.relay.fm/material" rel="noopener noreferrer"&gt;Material Podcast&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Two people known for their other shows, Andy Ihnatko of MacBreak Weekly and Florence Ion of All About Android, joined forces to create Material Podcast. All things Android, with quite a bit of easygoing fire-side chatter and entertaining points of view.  &lt;/p&gt;

&lt;p&gt;&lt;small&gt;Material Podcast &lt;a href="https://itunes.apple.com/us/podcast/material/id1015422651" rel="noopener noreferrer"&gt;iTunes&lt;/a&gt; | Material Podcast &lt;a href="https://www.relay.fm/material/feed" rel="noopener noreferrer"&gt;RSS&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  23. &lt;a href="https://www.twit.tv/shows/all-about-android" rel="noopener noreferrer"&gt;All About Android&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Along with Android Central's podcast, this is probably the Android show for the Android faithful. When a bunch of people passionate about Android, get together and spill their frustrations and excitement and hopes and experiences, no matter what you think about Android, you're in for a great show.&lt;/p&gt;

&lt;p&gt;&lt;small&gt;All About Android &lt;a href="https://podcasts.apple.com/us/podcast/all-about-android-mp3/id429307630?uo=10" rel="noopener noreferrer"&gt;iTunes&lt;/a&gt; | All About Android &lt;a href="http://feeds.twit.tv/aaa.xml" rel="noopener noreferrer"&gt;RSS&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Microsoft &amp;amp; Windows
&lt;/h2&gt;

&lt;p&gt;In recent years, Microsoft shifted a lot from a consumer-focused operating system and office software powerhouse, to a consumer and enterprise cloud and services company (with amazing consumer devices division, I must add!) In my personal opinion, this incredible turn of events doesn't get enough love and attention, but then again, data lakes and Azure Active Directory probably have a rather narrow audience. Nevertheless, a few shows do an excellent job covering all things Microsoft. &lt;/p&gt;

&lt;h3&gt;
  
  
  24. &lt;a href="https://www.twit.tv/shows/windows-weekly" rel="noopener noreferrer"&gt;Windows Weekly&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;If you're looking for some friendly venom from people covering Microsoft professionally, look no further. Sometimes I wonder why all the sarcasm, but then hosts go in-depth explains what's going on, why, since when, and what's next.  &lt;/p&gt;

&lt;p&gt;&lt;small&gt;Windows Weekly &lt;a href="https://podcasts.apple.com/us/podcast/windows-weekly-mp3/id197875368?uo=10" rel="noopener noreferrer"&gt;iTunes&lt;/a&gt; | Windows Weekly &lt;a href="http://feeds.twit.tv/ww.xml" rel="noopener noreferrer"&gt;RSS&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  25. &lt;a href="https://channel9.msdn.com/shows/This+Week+On+Channel+9/" rel="noopener noreferrer"&gt;This Week in Channel 9&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;This is a bit &lt;em&gt;meta&lt;/em&gt;. My colleague Christina Warren basically sums up all things Channel 9, Microsoft's outgoing stream of news, feature update talks, tech discussions, blog posts and so on. I also recommend &lt;a href="https://channel9.msdn.com/" rel="noopener noreferrer"&gt;Channel 9&lt;/a&gt; in its entirety, but be ready, it's a lot of great content. &lt;/p&gt;

&lt;p&gt;&lt;small&gt;TWiC9 &lt;a href="https://itunes.apple.com/gb/podcast/this-week-on-channel-9-mp4-channel-9/id360667463" rel="noopener noreferrer"&gt;iTunes&lt;/a&gt; | TWiC9 &lt;a href="https://channel9.msdn.com/Shows/This+Week+On+Channel+9/feed/mp3" rel="noopener noreferrer"&gt;RSS&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  26. &lt;a href="http://windowscentral.libsyn.com/" rel="noopener noreferrer"&gt;Windows Central Podcast&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Another quality show around all things Windows and Microsoft. More on the consumer side, I'd say, but it doesn't mean you don't get a comprehensive, in-depth look inside what's up and coming in Microsoft universe.&lt;/p&gt;

&lt;p&gt;&lt;small&gt;Windows Central &lt;a href="https://itunes.apple.com/us/podcast/windows-central-podcast/id1120948170?at=10l3Vy&amp;amp;ct=UUwpUdUnU40700YYwYwo5uw4zdpo5zwgzloorzgc3bomnxw2" rel="noopener noreferrer"&gt;iTunes&lt;/a&gt; | Windows Central &lt;a href="http://windowscentral.libsyn.com/rss" rel="noopener noreferrer"&gt;RSS&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  General
&lt;/h2&gt;

&lt;p&gt;This last category of shows is more on a general side of things, and not necessarily directly related to tech or software development. Still, these are excellent general interest shows.&lt;/p&gt;

&lt;h3&gt;
  
  
  27. &lt;a href="https://gimletmedia.com/shows/science-vs" rel="noopener noreferrer"&gt;Science Vs&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;One of the best popular science podcasts out there. I really wished it was more regular and I definitely would like to see more episodes more often. But honestly, I'm not sure one can produce more content of this quality without sacrificing depth of the research and all the things that come in before you even begin recording.&lt;/p&gt;

&lt;p&gt;&lt;small&gt;Science Vs &lt;a href="https://itunes.apple.com/us/podcast/science-vs/id1051557000?mt=2&amp;amp;at=1000lSb9&amp;amp;ct=gimweb" rel="noopener noreferrer"&gt;iTunes&lt;/a&gt; | Science Vs &lt;a href="https://feeds.megaphone.fm/sciencevs" rel="noopener noreferrer"&gt;RSS&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  28. &lt;a href="https://www.relay.fm/liftoff" rel="noopener noreferrer"&gt;Liftoff&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;For all of us space fans and enthusiasts, this is &lt;em&gt;the&lt;/em&gt; space show. Latest news, tech advancements, plans and the reality of the space age, all the things we love and enjoy, nicely packed and unraveled by people with deep passion for space.&lt;/p&gt;

&lt;p&gt;&lt;small&gt;Liftoff &lt;a href="https://itunes.apple.com/us/podcast/liftoff/id1031275911" rel="noopener noreferrer"&gt;iTunes&lt;/a&gt; | Liftoff &lt;a href="https://www.relay.fm/liftoff/feed" rel="noopener noreferrer"&gt;RSS&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  29. &lt;a href="https://www.intercom.com/blog/podcasts/" rel="noopener noreferrer"&gt;Inside Intercom&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;A little bit on a corporate side of things, but nevertheless informative in general for those following SaaS and tech industry. A lot of really huge names stopped by Intercom's virtual studios to share their journey to success.&lt;/p&gt;

&lt;p&gt;&lt;small&gt;Inside Intercom &lt;a href="https://itunes.apple.com/us/podcast/inside-intercom-podcast/id996103731?mt=2" rel="noopener noreferrer"&gt;iTunes&lt;/a&gt; | Inside Intercom &lt;a href="https://rss.art19.com/inside-intercom" rel="noopener noreferrer"&gt;RSS&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  30. &lt;a href="https://99percentinvisible.org/" rel="noopener noreferrer"&gt;99% Invisible&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;This one is again a more on a general interest side of things. Still, it's a lot of fun and inspiration, and thought-provoking conversations, neatly packed in a 30-60 minutes.&lt;/p&gt;

&lt;p&gt;&lt;small&gt;99% invisible &lt;a href="https://itunes.apple.com/us/podcast/99-invisible/id394775318?at=10l9zE" rel="noopener noreferrer"&gt;iTunes&lt;/a&gt; | 99% invisible &lt;a href="http://feeds.99percentinvisible.org/99percentinvisible" rel="noopener noreferrer"&gt;RSS&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;

</description>
      <category>podcast</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>Live Coding vs Imposter Paralysis</title>
      <dc:creator>Art Rosnovsky</dc:creator>
      <pubDate>Sun, 09 Jun 2019 01:40:05 +0000</pubDate>
      <link>https://dev.to/rosnovsky/live-coding-vs-imposter-paralysis-4p9l</link>
      <guid>https://dev.to/rosnovsky/live-coding-vs-imposter-paralysis-4p9l</guid>
      <description>&lt;p&gt;It's baffles me to say this out loud, but for the last month I've been working at &lt;a href="https://microsoft.com/"&gt;Microsoft&lt;/a&gt;. I've been building a proof-of-concept for an internal client search application and an interface for it. It's been a journey, that's for sure. From getting proper access and setting things up in general, to acquiring specific permissions to databases, figuring out hosting and deployment with &lt;a href="https://portal.azure.com/"&gt;Azure&lt;/a&gt;, solving AAD authentication issues, and burning midnight oil when some stupid bug prevented the app from running. &lt;/p&gt;

&lt;p&gt;I'm not writing or talking much about any of this: I've got a severe case of imposter syndrome called &lt;em&gt;imposter paralysis&lt;/em&gt;, and it feels like &lt;em&gt;everything&lt;/em&gt; I've been doing as a developer so far is some sort of shenanigans that I've managed to pull off somehow. Every morning when I get to work I think to myself that today is the day I get discovered. And every time on my long commute back home I'm surprised if not perplexed by the fact that no catastrophe unraveled. Moreover, I'd made some good progress, fixed a few blocking issues I had no clue how to approach earlier this morning, and that I'm clearly on track to demo the app on time at the end of my contract in late June. &lt;/p&gt;

&lt;p&gt;This weird mental limbo got me thinking. What if I'm not, in fact, an imposter? What if my skill is not completely made up? What if I am, for all intents and purposes, a programmer? Come to think of it, I'm writing programs. I'm building applications. However simple or boring they might be, they solve clients' problems and deliver exactly what they asked for, on time. I write code and some smart people are happy to pay me for it, so long as it does what it's supposed to do.&lt;/p&gt;

&lt;p&gt;But when I say "I'm coding" what I really mean is I stumble upon something I don't know or can't remember how to do, google it, google it some more, google the shit out of it, try a dozen of different ways to get where I need to be, figure things out after all, and fist-pump when it all starts to click. In my mind, however, &lt;em&gt;real programmers&lt;/em&gt; just code: they know what to type into their IDE right away, with all the syntax, patterns, and algorithms at the tip of their fingers, ready to go.&lt;/p&gt;

&lt;p&gt;One thing I found very helpful and even empowering is watching other people code live. I'm not talking about nicely edited tutorials and polished explainer videos with titles and lower-thirds, but about people just turning on their screen capture software and webcams, and streaming whatever happens next. Apparently, other people google too, and make silly mistakes, and do weird stuff for seemingly no reason, and squash them pesky bugs, and refer to StackOverflow, and so much more! Watching people &lt;a href="https://www.twitch.tv/team/livecoders"&gt;live code&lt;/a&gt; was an eye-opener, and a thrill! Not the nail-biting kind of thrill, but the kind where you're thrilled to see people make mistakes, get frustrated, answer questions, get confused by their own code, but figure it out more often then not. And most of the videos I've seen have this theme in them: &lt;em&gt;this kind of stuff helps you get better at coding and overcome imposter syndrome&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;So, with &lt;em&gt;extreme&lt;/em&gt; anxiety bordering on full-on panic, I announce that &lt;strong&gt;I will be live-streaming some of my coding sessions on &lt;a href="https://www.twitch.tv/rosnovsky"&gt;Twitch&lt;/a&gt;&lt;/strong&gt;. Please, follow, subscribe, and join in. I will be talking a lot, google even more, and use StackOverflow obsessively. It's also going to be "if you see something, say something" situation, so when you see me doing something completely idiotic and totally stupid, please, let me know. &lt;/p&gt;

&lt;p&gt;I, obviously, haven't &lt;em&gt;made it&lt;/em&gt; as a developer yet; I occasionally struggle to find work, and I struggle to land a truly good job (and not because I'm picky, mind you). So this is not a "looking back to my early days" kind of story. I realize that this post might bite me from the job search standpoint (who wants to hire an imposter, right?!), but I feel very strongly that unless I get over this whole imposter paralysis situation, I myself will keep hurting my own job search success even more. I don't expect my live stream to be of significant educational value to anyone but myself; I do, however, hope that it will help at least one person realize that you don't have to know everything in order to code, that coding is sometimes messy, and you make mistakes, and you search for answers, and none of the above makes you less of a developer.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>challenge</category>
      <category>personalnews</category>
    </item>
  </channel>
</rss>
