Keypress
KeyPress - an open-source blogging platform + free custom domains.
Install / Use
/learn @zernonia/KeypressREADME
<br />
<p align="center">
<a href="https://github.com/zernonia/keypress">
<img src="public/logo.svg" alt="KeyPress's Logo" width="80">
</a>
<br />
<p align="center">
A keyboard-first blogging platform. <br>
Finally write your blog post only with keys 🎹
</p>
<p align="center">
<a href="https://keypress.blog/">View Demo</a>
·
<a href="https://github.com/zernonia/keypress/issues">Report Bug</a>
·
<a href="https://github.com/zernonia/keypress/issues">Request Feature</a>
</p>
</p>
<br/>

Introduction
KeyPress is an open-source blogging platform that focused on keyboard-first experience. It was inspired by Vercel's Platform Starter Kit.
I always wanted to build a multi-tenant platform using Nuxt3, and I finally did it! - in nuxt-rc11.
If you are interested to implement the same, checkout
server/middleware/subdomain.ts- check the current domain and set srr context.app/router.option.ts- based on the ssr context, map a new route.pages/user/[siteId]- this will now be your new router root
🚀 Features
- 🤩 Free
- 📖 Open-Source
- 🚀 Free custom domain
- 🌌 Auto OG image (using Satori)
🔨 Built With
🌎 Setup
Prerequisites
Yarn
-
npm install --global yarn
Development
- Clone the repo
git clone https://github.com/zernonia/keypress.git - Install NPM packages
cd keypress yarn install - Run local development instance
yarn dev
Supabase Database
create table domains (
user_id uuid,
url text not null primary key,
active boolean,
created_at timestamp default now()
);
create table profiles (
id uuid default uuid_generate_v4() primary key,
username text,
avatar_url text,
name text,
created_at timestamp default now(),
subdomain text references domains (url)
);
create table posts (
id uuid default uuid_generate_v4() primary key,
author_id uuid references profiles (id),
created_at timestamp default now(),
slug text not null,
title text,
body text,
cover_img text,
active boolean,
tags ARRAY,
featured boolean not null
);
create or replace view tags_view as
select *, count(*)
from
(select unnest(tags) as name from posts where active is true) s
group by name;
create or replace function public.handle_new_user()
returns trigger as $$
begin
insert into public.profiles (id, avatar_url, username, name)
values (new.id, new.raw_user_meta_data->>'avatar_url', new.raw_user_meta_data->>'user_name', new.raw_user_meta_data->>'preferred_username');
return new;
end;
$$ language plpgsql security definer;
create trigger on_auth_user_created
after insert on auth.users
for each row execute procedure public.handle_new_user();
➕ Contributing
Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are greatly appreciated.
- Fork the Project
- Create your Feature Branch (
git checkout -b feature/AmazingFeature) - Commit your Changes (
git commit -m 'Add some AmazingFeature') - Push to the Branch (
git push origin feature/AmazingFeature) - Open a Pull Request
Acknowledgement
- Nuxt 3 - Awesome framework
- Supabase - Super easy setup (as always)
- Tiptap - Awesome editor
- Vercel's Platform Starter Kit - Subdomain/Custom domain
- Vercel's new og generation
Author
- Zernonia (@zernonia)
Also, if you like my work, please buy me a coffee ☕😳
<a href="https://www.buymeacoffee.com/zernonia" target="_blank"> <img src="https://www.buymeacoffee.com/assets/img/custom_images/yellow_img.png" alt="Logo" > </a>🔥 Contributors
<a href="https://github.com/zernonia/keypress/graphs/contributors"> <img src="https://contrib.rocks/image?repo=zernonia/keypress" /> </a>📜 License
Distributed under the MIT License. See LICENSE for more information.
