-
Productivity focused Do everything from the comfort of your keyboard.
-
Shareable Pages are publicly readable by anyone with the link.
-
Optimized for performance Aggressive caching, small code bundles and native font stacks.
-
Browser Extension Packaged as an extension to replace your homepage (firefox, chrome).
The page structure is defined entirely by the document. Instead of adding, updating and removing links with buttons, targetblank uses text to represent your page. Although the syntax is completely different, it works similarly to other structured documents like markdown or yaml.
A minimal document contains at least a version line and a header line. The version is the first thing the parser reads, and it makes it easier to keep the format backwards-compatible if the syntax needs to change in the future.
+ version 1
+ ===
The space between the version and header lines is used for metadata about the page. For now, this only allows the page's title to be configured, but please open an issue to share your ideas (ex. background image). The format of a metadata entry is a name, followed by =
and finally the value.
version 1
+ title = Hello World!
===
Your links are added after the header line and can be formatted in two ways. The simplest way is to simply write the link on its own line, the parser will make sure it's detected and clickable. Alternatively, links can be labelled, which lets you control what text is displayed in place of the full link.
version 1
title = Hello World
===
+ example.com?q=foo
+ labelled link [example.com?q=bar]
You can also add labels on their own, without a link. These will not be clickable, but can be a convenient way to organize your links. For even more control, the links and labels can be indented into whatever shape makes sense for your use case.
version 1
title = Hello World
===
+ productivity
example.com?q=foo
+ example.com/baz
labelled link [example.com?q=bar]
When a single group isn't enough, you can add a group delimiter to create a new one and add more links. This will be reflected on the homepage by a new section side-by-side with the first one. After a few groups (depending on the size of your screen) they will start wrapping underneath the first row of sections on the homepage.
version 1
title = Hello World
===
productivity
example.com?q=foo
example.com/baz
labelled link [example.com?q=bar]
---
+ communication
+ example.com/chat
Keyboard Shortcuts
Targetblank is meant to be usable and productive using only a keyboard. The document format goes a long way towards making that a reality, but these shortcuts help complete the story, adding quick navigation and useful text-editing commands. The editor shortcuts are inspired by common text editor keybindings and work on multi-line selections. If your favorite shortcut is missing, please let me know.
Page |
Shortcut |
Keys |
Homepage |
Open editor |
shift + e |
|
Search links |
<any letters> |
|
Follow link |
enter |
Editor |
Close editor |
esc |
|
Indent |
tab |
|
|
ctrl + ] |
|
Un-indent |
shift + tab |
|
|
ctrl + [ |
|
Move up |
alt + up |
|
Move down |
alt + down |
|
Toggle comment |
ctrl + / |
Development
$ npm run dev
This will launch a local server which watches and serves contents from ./website
.
The api is not mocked in dev mode, it points to production endpoints.
Testing
$ go test ./...
Tests all backend packages (routing, handler logic and document parsing).
$ npm run test
Checks code quality, runs unit tests on helpers and builds the bundle.
Extension
Developing the extension starts the same as usual website development.
$ npm run build:extension
Chrome: navigate to chrome://extensions
, enable developer mode, and load unpacked from the .extension
directory.
Firefox: navigate to about:debugging#/runtime/this-firefox
, and load temporary add-on from any file in the .extension
directory.
You will need to open a new tab to view the most recent version of the extension (no hot-reload).
Sourcing the extension contents from .website
will use the actual bundle, but will not be updated on save.
Deployment
This project is hosted on AWS and uses Terraform to manage the cloud resources.
The deployment workflow uses GitHub Actions to package and apply changes on every change to master.
Deployment to the extension stores runs in the same deployment pipeline as the website. New versions will only be published when the manifest's version changes.
API
The API is rooted at https://api.targetblank.org
. Details about arguments and return values can be found by following the links to the function implementations.
The addr
path parameter represents the six character string which identifies a page.
Function |
Description |
Method |
Path |
authenticate |
Create authentication token |
POST |
/auth/:addr |
passwd * |
Update page password |
PUT |
/auth/:addr |
reset |
Request page password reset |
DELETE |
/auth/:addr |
create |
Create new page |
POST |
/page |
read ** |
Fetch page content |
GET |
/page/:addr |
update * |
Edit page document |
PUT |
/page/:addr |
validate |
Validate page document |
POST |
/page/validate |
* Authentication required.
** Authentication may be required depending on page configuration.
Schema
All data is stored in a single page
table. Each item represents both a single page and its owner.
Attribute |
Raw Type |
Description |
addr |
string |
Page address (key) |
document |
string |
Parsed document stored as JSON |
email |
string |
Hashed page email |
password |
string |
Hashed page password |
password_last_update |
string |
Timestamp of when the password was last updated |
published |
bool |
Published pages are readable without authentication |
License
MIT