<?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: Ahmet ALMAZ</title>
    <description>The latest articles on DEV Community by Ahmet ALMAZ (@music47ell).</description>
    <link>https://dev.to/music47ell</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%2F78730%2Fc80931d6-e697-4e58-a713-5637efd9bd4d.png</url>
      <title>DEV Community: Ahmet ALMAZ</title>
      <link>https://dev.to/music47ell</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/music47ell"/>
    <language>en</language>
    <item>
      <title>Maestral Review: Your Solution to Ignoring node_modules in Dropbox</title>
      <dc:creator>Ahmet ALMAZ</dc:creator>
      <pubDate>Thu, 03 Aug 2023 08:13:24 +0000</pubDate>
      <link>https://dev.to/news47ell/maestral-review-your-solution-to-ignoring-nodemodules-in-dropbox-58ig</link>
      <guid>https://dev.to/news47ell/maestral-review-your-solution-to-ignoring-nodemodules-in-dropbox-58ig</guid>
      <description>&lt;p&gt;Facing challenges when backing up projects to Dropbox is a common issue for Node.js developers, mainly because of the large and frequently updated &lt;code&gt;node_modules&lt;/code&gt; folder. Nevertheless, the good news is that &lt;a href="https://maestral.app/" rel="noopener noreferrer"&gt;&lt;strong&gt;Maestral&lt;/strong&gt;&lt;/a&gt; offers an innovative solution through its &lt;code&gt;.mignore&lt;/code&gt; feature, allowing developers to seamlessly address this problem without the need to switch to a different cloud storage provider.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Info: ICYMI, I recently wrote two articles about how to exclude node_modules from syncing during backup. The first one uses &lt;a href="https://www.news47ell.com/blog/sync-node-project-ignore-node-modules-rsync-bash-script" rel="noopener noreferrer"&gt;rsync&lt;/a&gt; and the second one uses &lt;a href="https://www.news47ell.com/blog/filen-review-dropbox-alternative-exclude-node-modules-sync" rel="noopener noreferrer"&gt;Filen&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Maestral's &lt;code&gt;.mignore&lt;/code&gt; feature functions similarly to the &lt;code&gt;.gitignore&lt;/code&gt; in version control systems, empowering developers to exclude the bulky &lt;code&gt;node_modules&lt;/code&gt; directory from syncing. This exclusion leads to faster backups and optimizes Dropbox storage usage.&lt;/p&gt;

&lt;p&gt;In this review, we will delve into the essential aspects of Maestral and explore how it enhances the management of Dropbox files for Node.js developers, offering them more effective and efficient solutions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Powerful Command Line Interface:
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://maestral.app/" rel="noopener noreferrer"&gt;Maestral's&lt;/a&gt; command line interface (CLI) is a robust tool that puts users in control of their Dropbox files directly from the terminal.&lt;/p&gt;

&lt;p&gt;This command line functionality provides a seamless and efficient way to manage Dropbox files without the need for a graphical user interface.&lt;/p&gt;

&lt;p&gt;Here are 3 things you can do with Maestral's CLI:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://maestral.app/cli/restore" rel="noopener noreferrer"&gt;View and restore previous file versions&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://maestral.app/cli/sharelink" rel="noopener noreferrer"&gt;Create and revoke shared links&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://maestral.app/cli/activity" rel="noopener noreferrer"&gt;Monitor live sync activity&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Multiple Dropbox Accounts:
&lt;/h2&gt;

&lt;p&gt;Maestral's CLI supports the configuration of an unlimited number of Dropbox accounts. Users can conveniently manage multiple Dropbox accounts by simply passing a &lt;a href="https://maestral.app/docs/configfile" rel="noopener noreferrer"&gt;new configuration name&lt;/a&gt; when linking a new account.&lt;/p&gt;

&lt;p&gt;This feature is particularly valuable for individuals who need to separate personal and professional Dropbox accounts or manage multiple client accounts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Unlimited Number of Devices:
&lt;/h2&gt;

&lt;p&gt;Maestral offers the flexibility of connecting an unlimited number of devices to your Dropbox account without being restricted by the three-device limit imposed on Basic Dropbox accounts. Since Maestral is not an official Dropbox app, it does not count toward the device limit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Effortless &lt;code&gt;.mignore&lt;/code&gt; Integration:
&lt;/h2&gt;

&lt;p&gt;Maestral's &lt;a href="https://maestral.app/docs/mignore" rel="noopener noreferrer"&gt;&lt;code&gt;.mignore&lt;/code&gt;&lt;/a&gt; feature allows Node.js developers to effortlessly exclude the &lt;code&gt;node_modules&lt;/code&gt; folder from Dropbox synchronization.&lt;/p&gt;

&lt;p&gt;By creating an &lt;code&gt;.mignore&lt;/code&gt; file in the root directory of your Dropbox account and specifying patterns, you can easily prevent the &lt;code&gt;node_modules&lt;/code&gt; directory from being uploaded. This simple solution ensures that only essential project files are synced, saving you time and storage space while maintaining the integrity of your project.&lt;/p&gt;

&lt;p&gt;To use Maestral to ignore the &lt;code&gt;node_modules&lt;/code&gt; folder, you can follow these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://maestral.app/download/" rel="noopener noreferrer"&gt;Install Maestral&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create an &lt;code&gt;.mignore&lt;/code&gt; file in the root directory of your Dropbox account.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add the following line to the &lt;code&gt;.mignore&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;node_modules
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Save the &lt;code&gt;.mignore&lt;/code&gt; file.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Once you have followed these steps, Maestral will ignore the &lt;code&gt;node_modules&lt;/code&gt; folder in Dropbox. This will save you time and storage space, and it will also improve the performance of your syncs.&lt;/p&gt;

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

&lt;p&gt;In conclusion, &lt;a href="https://maestral.app/" rel="noopener noreferrer"&gt;Maestral&lt;/a&gt; combines the power of its command line interface with various essential features.&lt;/p&gt;

&lt;p&gt;These features provide a comprehensive and efficient Dropbox management solution, making Maestral an excellent choice for users looking to enhance their Dropbox experience.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>node</category>
      <category>nextjs</category>
    </item>
    <item>
      <title>Revolutionize Your Cloud Storage: Exclude node_modules with Filen</title>
      <dc:creator>Ahmet ALMAZ</dc:creator>
      <pubDate>Wed, 12 Jul 2023 15:52:04 +0000</pubDate>
      <link>https://dev.to/news47ell/revolutionize-your-cloud-storage-exclude-nodemodules-with-filen-2pf4</link>
      <guid>https://dev.to/news47ell/revolutionize-your-cloud-storage-exclude-nodemodules-with-filen-2pf4</guid>
      <description>&lt;p&gt;If you're a web developer who uses npm packages and backs up projects to Dropbox, chances are you've searched for a way to exclude the node_modules directory from syncing.&lt;/p&gt;

&lt;p&gt;In the past, I relied on a custom bash script that used rsync to copy folders to a Dropbox folder while excluding certain files, folders, and everything listed in a .gitignore file. Although this solution worked well, it meant maintaining two copies of the backup.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Info: Make sure to check out my tutorial on &lt;a href="https://www.news47ell.com/blog/sync-node-project-ignore-node-modules-rsync-bash-script" rel="noopener noreferrer"&gt;How to Use rsync to Sync a Node Project to Dropbox and Ignore the node modules Folder&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But now, with the introduction of Filen, things have changed. Filen is an alternative to Dropbox that offers advanced syncing options, including the ability to exclude the node_modules folder from syncing. No more worries about duplicating unnecessary files!&lt;/p&gt;

&lt;p&gt;Well, with the introduction of &lt;a href="https://www.news47ell.com/recommends/filen?ref=news47ell.com" rel="noopener noreferrer"&gt;Filen&lt;/a&gt;, I don't have to worry about this anymore. Filen is a Dropbox alternative that allows you to exclude the &lt;code&gt;node_modules&lt;/code&gt; folder from syncing and so much more.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introducing Filen: A Dropbox Alternative with Advanced Syncing Options
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.news47ell.com/recommends/filen?ref=news47ell.com" rel="noopener noreferrer"&gt;Filen&lt;/a&gt; is a zero knowledge end-to-end encrypted cloud storage that has all the features that you love and are used to from &lt;a href="https://www.news47ell.com/recommends/dropbox?ref=news47ell.com" rel="noopener noreferrer"&gt;Dropbox&lt;/a&gt;, as well as an easy-to-use interface, encryption for all your data in a German high-security data center, the ability to share files and pictures using a private link or with other Filen users, syncing your data across multiple devices, ability to backup your camera folder from your phone automatically and selective sync option as well.&lt;/p&gt;

&lt;p&gt;All of this is cool but one &lt;code&gt;node_modules&lt;/code&gt; folder can ruin all of this for a web developer.&lt;/p&gt;

&lt;p&gt;For those of you who don't know, a &lt;code&gt;node_modules&lt;/code&gt; folder contains all the necessary files to run a Node.js project. Like this website that uses Next.js. The problem with it is that it can be large and time-consuming to sync due to its size and frequent updates.&lt;/p&gt;

&lt;p&gt;For example, the &lt;code&gt;node_modules&lt;/code&gt; folder for this website is '632.9 MB' and it contains '48,363' files. That takes forever to sync and any update, removal, or installation of a new module means syncing again and again.&lt;/p&gt;

&lt;p&gt;With &lt;a href="https://www.news47ell.com/recommends/filen?ref=news47ell.com" rel="noopener noreferrer"&gt;Filen&lt;/a&gt;, you don't have to worry about any of this. See, Filen has a neat feature that allows you to select files and folders to be ignored while syncing. Like a &lt;code&gt;.gitignore&lt;/code&gt; file. They call it actually &lt;code&gt;.filenignore&lt;/code&gt; file but in reality, it's not a file, it's a section in the app where you list the files and folders and it will do the rest.&lt;/p&gt;

&lt;p&gt;Imagine having a Projects folder housing all your web development projects. By instructing Filen to sync the folder and selecting your &lt;a href="https://filen.io/apps/desktop" rel="noopener noreferrer"&gt;preferred sync option&lt;/a&gt; (e.g., two-way, local to cloud, cloud to local, local backup, or cloud backup), you can then utilize the &lt;code&gt;.filenignore&lt;/code&gt; option to exclude the &lt;code&gt;node_modules&lt;/code&gt; folder from syncing.&lt;/p&gt;

&lt;p&gt;Let Filen handle the synchronization while you focus on your development tasks, saving you time and ensuring a seamless experience.&lt;/p&gt;

&lt;p&gt;You can sign up to &lt;a href="https://www.news47ell.com/recommends/filen?ref=news47ell.com" rel="noopener noreferrer"&gt;Filen&lt;/a&gt; for free and we both get 10 GB of storage space. If you need more, you can upgrade to a paid plan. The paid plans start at 11.99€ annually for 100 GB of storage space or, you can pay 29.99€ for a lifetime plan with 100 GB of storage space. You can check out the &lt;a href="https://filen.io/pricing" rel="noopener noreferrer"&gt;pricing page&lt;/a&gt; for more options.&lt;/p&gt;

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

&lt;p&gt;Say goodbye to the hassle of dealing with large &lt;code&gt;node_modules&lt;/code&gt; folders during syncing.&lt;/p&gt;

&lt;p&gt;Let &lt;a href="https://www.news47ell.com/recommends/filen?ref=news47ell.com" rel="noopener noreferrer"&gt;Filen&lt;/a&gt; revolutionize your cloud storage experience by providing a simple yet powerful solution for excluding these folders effortlessly.&lt;/p&gt;

</description>
      <category>cloudstorage</category>
      <category>e2ee</category>
      <category>node</category>
      <category>nextjs</category>
    </item>
    <item>
      <title>Use rsync to Sync a Node Project to Dropbox and Ignore the node modules Folder</title>
      <dc:creator>Ahmet ALMAZ</dc:creator>
      <pubDate>Tue, 13 Jun 2023 18:00:00 +0000</pubDate>
      <link>https://dev.to/news47ell/use-rsync-to-sync-a-node-project-to-dropbox-and-ignore-the-node-modules-folder-5fp2</link>
      <guid>https://dev.to/news47ell/use-rsync-to-sync-a-node-project-to-dropbox-and-ignore-the-node-modules-folder-5fp2</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This article &lt;a href="https://www.news47ell.com/blog/sync-node-project-ignore-node-modules-rsync-bash-script" rel="noopener noreferrer"&gt;Use rsync to Sync a Node Project to Dropbox and Ignore the node modules Folder&lt;/a&gt; was &lt;a href="https://www.news47ell.com/" rel="noopener noreferrer"&gt;originally posted on News47ell.com&lt;/a&gt;. For more articles like this, &lt;a href="https://www.news47ell.com/blog" rel="noopener noreferrer"&gt;click here&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When working on Node.js projects, it's common to have a large number of dependencies installed in the &lt;code&gt;node_modules&lt;/code&gt; folder. This folder can be quite large and can slow down the syncing process when backing up or transferring your project to &lt;a href="https://www.news47ell.com/recommends/dropbox" rel="noopener noreferrer"&gt;Dropbox&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To overcome this issue, you can use &lt;a href="https://rsync.samba.org/" rel="noopener noreferrer"&gt;rsync&lt;/a&gt;, a powerful command-line tool for synchronizing files and directories, along with a bash script that excludes the &lt;code&gt;node_modules&lt;/code&gt; folder and also filter out anything in a &lt;code&gt;.gitignore&lt;/code&gt; file that you specify. In this article, I'll guide you through the process of setting up and using this bash script to sync your Node.js project while ignoring the &lt;code&gt;node_modules&lt;/code&gt; folder.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Create the Bash Script
&lt;/h2&gt;

&lt;p&gt;To get started, open your favorite text editor and create a new file. You can name it something like &lt;code&gt;sync-node-projects.sh&lt;/code&gt;. Paste the following code into the file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/usr/bin/env bash&lt;/span&gt;

&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="c"&gt;# Exit on error&lt;/span&gt;

&lt;span class="nv"&gt;src_dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/Projects/"&lt;/span&gt;
&lt;span class="nv"&gt;dest_dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/Dropbox/Projects-Backup/"&lt;/span&gt;

&lt;span class="c"&gt;# run rsync&lt;/span&gt;
rsync &lt;span class="nt"&gt;-a&lt;/span&gt; &lt;span class="nt"&gt;--delete&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--filter&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;':- .gitignore'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--exclude&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'node_modules'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--exclude&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'.git'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--exclude&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'.DS_Store'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--chmod&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'F-w'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$src_dir&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$dest_dir&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's go through the script and understand what each part does:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The first line (&lt;code&gt;#!/usr/bin/env bash&lt;/code&gt;) specifies the interpreter for the script as bash.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;set -e&lt;/code&gt; command ensures that the script exits immediately if any command within it returns a non-zero status, indicating an error.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;src_dir&lt;/code&gt; variable defines the source directory path, where your Node.js project is located. Update it with the appropriate path for your system.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;dest_dir&lt;/code&gt; variable defines the destination directory path, where you want to backup or transfer your project. Modify it to suit your needs.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;rsync&lt;/code&gt; command is responsible for synchronizing the files and directories. Let's examine its options:

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;-a&lt;/code&gt; flag stands for "archive mode" and is a convenient way to sync files while preserving their permissions, ownership, and other attributes.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;--delete&lt;/code&gt; option ensures that any files or directories that exist in the destination but not in the source are deleted during the sync. This helps keep both locations identical.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;--filter=':- .gitignore'&lt;/code&gt; flag excludes files and directories specified in the &lt;code&gt;.gitignore&lt;/code&gt; file from being synced. This ensures that files ignored by Git are also ignored by rsync.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;--exclude='node_modules'&lt;/code&gt; option tells rsync to skip syncing the &lt;code&gt;node_modules&lt;/code&gt; folder, which can be large and unnecessary for backup or transfer purposes.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;--exclude='.git'&lt;/code&gt; flag excludes the &lt;code&gt;.git&lt;/code&gt; folder, as it is not required for syncing and can be quite large.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;--exclude='.DS_Store'&lt;/code&gt; option excludes the &lt;code&gt;.DS_Store&lt;/code&gt; file, which is specific to macOS and contains metadata that is not relevant for syncing.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;--chmod='F-w'&lt;/code&gt; flag removes write permissions from all files in the destination directory, ensuring they remain read-only. This prevents accidental modifications in the backup location.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 2: Save and Make the Script Executable
&lt;/h2&gt;

&lt;p&gt;After pasting the script into your text editor, save the file and navigate to the location where you saved it using the terminal. To make the script executable, run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;chmod&lt;/span&gt; +x sync-node-project.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command grants execute permissions to the script.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Run the Script
&lt;/h2&gt;

&lt;p&gt;To sync your Node.js project, open a terminal and navigate to the location of the script. Execute the script by running the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./sync-node-project.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The script will start syncing your Node.js project from the source directory (&lt;code&gt;src_dir&lt;/code&gt;) to the destination directory (&lt;code&gt;dest_dir&lt;/code&gt;), excluding the &lt;code&gt;node_modules&lt;/code&gt; folder.&lt;/p&gt;

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

&lt;p&gt;Congratulations! You have successfully set up a bash script that uses rsync to sync your Node.js project while ignoring the &lt;code&gt;node_modules&lt;/code&gt; folder. By excluding this folder from the syncing process, you can save time and space, especially when working with large projects. Remember to run the script whenever you want to sync your project, and all your changes will be transferred while keeping the unnecessary &lt;code&gt;node_modules&lt;/code&gt; folder out of the equation.&lt;/p&gt;

</description>
      <category>node</category>
      <category>nextjs</category>
      <category>bash</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Real-time page views with Next.js, Turso and Drizzle ORM</title>
      <dc:creator>Ahmet ALMAZ</dc:creator>
      <pubDate>Fri, 02 Jun 2023 20:03:45 +0000</pubDate>
      <link>https://dev.to/news47ell/real-time-page-views-with-nextjs-turso-and-drizzle-orm-3dl0</link>
      <guid>https://dev.to/news47ell/real-time-page-views-with-nextjs-turso-and-drizzle-orm-3dl0</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This article &lt;a href="https://www.news47ell.com/blog/page-views-nextjs-turso-drizzle-orm" rel="noopener noreferrer"&gt;Real-time page views with Next.js, Turso and Drizzle ORM&lt;/a&gt; was &lt;a href="https://www.news47ell.com/" rel="noopener noreferrer"&gt;originally posted on News47ell.com&lt;/a&gt;. For more articles like this, &lt;a href="https://www.news47ell.com/blog" rel="noopener noreferrer"&gt;click here&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you're searching for a simple and effective method to incorporate real-time page views into your Next.js website, you've come across the perfect tutorial on this topic. In this article, I will guide you through the process of integrating real-time page views into your Next.js website using Turso and Drizzle ORM.&lt;/p&gt;

&lt;h2&gt;
  
  
  Turso: A Game-Changing SQLite Edge Database
&lt;/h2&gt;

&lt;p&gt;Let me introduce you to &lt;a href="https://turso.tech/" rel="noopener noreferrer"&gt;Turso&lt;/a&gt;, the groundbreaking SQLite edge database that will revolutionize your website. Turso is built on the robust libSQL framework and offers an astonishing free plan that lasts indefinitely. With this plan, you'll enjoy a generous 8 GB of total storage and the ability to create up to 3 databases across 3 different locations. Prepare to have your expectations completely exceeded!&lt;/p&gt;

&lt;h2&gt;
  
  
  Drizzle ORM: The Cutting-Edge Object-Relational Mapping Library
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://drizzle.team/" rel="noopener noreferrer"&gt;Drizzle ORM&lt;/a&gt; is an advanced object-relational mapping library designed specifically for Node.js and TypeScript applications. This powerhouse provides comprehensive support for multiple databases, migrations, and query building. It's like having a turbocharged engine powering your website!&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup Turso database
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Install the Turso CLI (For more options &lt;a href="https://docs.turso.tech/tutorials/get-started-turso-cli/step-01-installation" rel="noopener noreferrer"&gt;Click here&lt;/a&gt;):
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;chiselstrike/tap/turso
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Sign up to Turso:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;turso auth signup
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Create a new database
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;turso db create &lt;span class="o"&gt;[&lt;/span&gt;db-name]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Get the URL of your database (Starts with &lt;code&gt;libsql://&lt;/code&gt;):
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;turso db show &lt;span class="o"&gt;[&lt;/span&gt;db-name]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Access your database shell:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;turso db shell &lt;span class="o"&gt;[&lt;/span&gt;db-name]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Create a new table for &lt;code&gt;views&lt;/code&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;IF&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;EXISTS&lt;/span&gt; &lt;span class="n"&gt;views&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;slug&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;count&lt;/span&gt; &lt;span class="nb"&gt;INTEGER&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Create an &lt;code&gt;auth&lt;/code&gt; token
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;turso db tokens create &lt;span class="o"&gt;[&lt;/span&gt;db-name] &lt;span class="nt"&gt;-e&lt;/span&gt; none
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Now inside &lt;code&gt;.env&lt;/code&gt; file, add the following:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;DATABASE_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;libsql://[db-url]
&lt;span class="nv"&gt;DATABASE_AUTH_TOKEN&lt;/span&gt;&lt;span class="o"&gt;=[&lt;/span&gt;auth-token]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Connect Next.js to Turso
&lt;/h2&gt;

&lt;p&gt;In order to connect our site to the database, we need to use Drizzle ORM. All we have to do is install couple of packages and set them up.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install Drizzle ORM and libSQL client:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i drizzle-orm @libsql/client
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Create a file &lt;code&gt;lib/turso.ts&lt;/code&gt; to initialize your Turso client
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&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;createClient&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;@libsql/client&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;drizzle&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;drizzle-orm/libsql&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;integer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sqliteTable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;text&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;drizzle-orm/sqlite-core&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;connection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createClient&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DATABASE_URL&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="na"&gt;authToken&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DATABASE_AUTH_TOKEN&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;drizzle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;connection&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;viewsTable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;sqliteTable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;views&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="na"&gt;slug&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;slug&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;primaryKey&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;integer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;count&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;notNull&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="k"&gt;default&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Now we create &lt;code&gt;app/api/views/[slug]/route.ts&lt;/code&gt; and use it to increment and fetch page views
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&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;eq&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;drizzle-orm&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="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;NextRequest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;NextResponse&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;next/server&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;z&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;zod&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;viewsTable&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;@/lib/turso&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Options&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;slug&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="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="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;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NextRequest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;Options&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;slug&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slug&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;data&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="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;viewsTable&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;viewsTable&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="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;all&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;count&lt;/span&gt; &lt;span class="o"&gt;=&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;length&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="nc"&gt;Number&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;count&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;NextResponse&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="nx"&gt;count&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;POST&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;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NextRequest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;Options&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;slug&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&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="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;viewsTable&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;viewsTable&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="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;all&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;count&lt;/span&gt; &lt;span class="o"&gt;=&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;length&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="nc"&gt;Number&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;count&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;viewsTable&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;slug&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;count&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="nf"&gt;onConflictDoUpdate&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;viewsTable&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="na"&gt;set&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;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="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;returning&lt;/span&gt;&lt;span class="p"&gt;()&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;NextResponse&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="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Finally, we create &lt;code&gt;ViewCounter.tsx&lt;/code&gt; component to display the page views which we can use in our blog posts
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;use client&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;useEffect&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;react&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;useSWR&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;swr&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;fetcher&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;@/lib/fetcher&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;PostView&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;@/lib/types&lt;/span&gt;&lt;span class="dl"&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ViewsCounter&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="nx"&gt;trackView&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;slug&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="nl"&gt;trackView&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&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="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;=&lt;/span&gt; &lt;span class="nx"&gt;useSWR&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;PostView&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`/api/views/&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="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fetcher&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;views&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;Number&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="nx"&gt;count&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="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;registerView&lt;/span&gt; &lt;span class="o"&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="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`/api/views/&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="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;trackView&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;registerView&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="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="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;p&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;"font-mono text-sm tracking-tighter"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;data&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="nx"&gt;views&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLocaleString&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="s2"&gt; views`&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;--- views&lt;/span&gt;&lt;span class="dl"&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;p&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;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Now we have a working page views counter that is connected to our Turso database. You can use this method to add page views to any website that is built with Next.js.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>turso</category>
      <category>nextjs</category>
      <category>orm</category>
    </item>
  </channel>
</rss>
