You may have stumbled upon this page after visiting PrivaNote (privanote.xyz).
PrivaNote is an offline first, end-to-end encrypted note taking solution. It's one of the first applications built on top of Portabella and serves as a reference for other developers looking to build their own apps.
With that said, let's dive into how we built this!
PrivaNote is a Next.js application with TailwindCSS to make it look pretty. The editor is a reasonably customised Slate instance. Setting up these components to play nicely is a breeze thanks to modern tooling.
Without setting up the encrypted backup PrivaNote will write to your browsers IndexedDB or LocalStorage. After setting up and initialising your Portabella configuration it will read and write from there.
Our initialisation script looked a little like this:
We took a lot of inspiration for our editor from one of the examples the slate-plugins library provides.
After scaffolding our application we needed to ensure it's offline first. That means we should be able to use it without an internet connection and without Portabella. For this we leveraged the localForage library. It tries to use IndexedDB and then falls back to LocalStorage if the browser doesn't have it.
We could have written this layer ourselves but it just made sense to bring in a dependency to make sure we didn't mess anything up.
To read all of our notes it looks a bit like this:
Creating a note is as easy as:
We won't show you the delete operation because, well, you get the gist.
Setting up our Portabella integration is a little trickier. We have a few additional constraints here, we need to:
- save Portabella config in our local database
- check if they have Portabella config before falling back to the local database storage
- prompt users to setup their Portabella integration (after 10 seconds to not be annoying).
Let's cover reading and writing data before we get to the administrative tasks. Writing a note to Portabella leveraging the @portabella/sdk is as easy as:
Reading all our notes (when we refresh the page for example looks like):
The SDK takes care of decrypting everything for us so we don't need to worry about getting data we can't read.
Before we can do the above operations we need to ensure we actually have Portabella config so we can initialise the SDK and make requests.
To do this we want to prompt the user to setup their integration after 10 seconds on PrivaNote. Additionally we don't want to prompt them again if they've already said yes (or no).
useEffect hook looks a bit like this:
Doing it this way allows for a seamless end user experience.
The final piece of the puzzle is packaging up the Next.js application for use as a browser extension. Having to manually open privanote.xyz everytime you want to take notes is a bit cumbersome, so the idea is to override the "new tab" page of your browser. That means pressing CMD (or CTRL) + N will open up PrivaNote, allowing you to jott down thoughts without thinking twice about it.
Here's our script we used to do this:
The most interesting lines are the ones that contain
<script src="/_next/a.js" /> tag won't work out of the box, we need to replace
next (or any string you prefer). The
sed command shown here works on Mac OS but you might have to fiddle with it if you're using a different OS.
Thanks for taking the time to checkout this tutorial, as we said PrivaNote is one of the first applications built on top of Portabella so we'll continue to improve documentation and APIs as we go and discover what's useful to people.